File Coverage

blib/lib/Rose/DB/Object/Metadata/Relationship/OneToMany.pm
Criterion Covered Total %
statement 31 41 75.6
branch 7 20 35.0
condition 7 18 38.8
subroutine 10 12 83.3
pod 3 6 50.0
total 58 97 59.7


line stmt bran cond sub pod time code
1             package Rose::DB::Object::Metadata::Relationship::OneToMany;
2              
3 1     1   7 use strict;
  1         2  
  1         31  
4              
5 1     1   5 use Carp();
  1         3  
  1         23  
6              
7 1     1   6 use Rose::DB::Object::Metadata::Relationship;
  1         2  
  1         59  
8             our @ISA = qw(Rose::DB::Object::Metadata::Relationship);
9              
10 1     1   7 use Rose::Object::MakeMethods::Generic;
  1         1  
  1         9  
11 1     1   22 use Rose::DB::Object::MakeMethods::Generic;
  1         2  
  1         6  
12              
13             our $Debug = 0;
14              
15             our $VERSION = '0.781';
16              
17             __PACKAGE__->default_auto_method_types(qw(find get_set_on_save add_on_save));
18              
19             __PACKAGE__->add_common_method_maker_argument_names
20             (
21             qw(class share_db key_columns manager_class manager_method
22             manager_count_method manager_iterator_method manager_find_method
23             manager_args query_args join_args)
24             );
25              
26             use Rose::Object::MakeMethods::Generic
27             (
28 1         8 boolean =>
29             [
30             'share_db' => { default => 1 },
31             ],
32              
33             hash =>
34             [
35             key_column => { hash_key => 'key_columns' },
36             key_columns => { interface => 'get_set_all' },
37             ],
38 1     1   101 );
  1         1  
39              
40             Rose::Object::MakeMethods::Generic->make_methods
41             (
42             { preserve_existing => 1 },
43             scalar =>
44             [
45             __PACKAGE__->common_method_maker_argument_names
46             ],
47             );
48              
49             __PACKAGE__->method_maker_info
50             (
51             count =>
52             {
53             class => 'Rose::DB::Object::MakeMethods::Generic',
54             type => 'objects_by_key',
55             interface => 'count',
56             },
57              
58             find =>
59             {
60             class => 'Rose::DB::Object::MakeMethods::Generic',
61             type => 'objects_by_key',
62             interface => 'find',
63             },
64              
65             iterator =>
66             {
67             class => 'Rose::DB::Object::MakeMethods::Generic',
68             type => 'objects_by_key',
69             interface => 'iterator',
70             },
71              
72             get_set =>
73             {
74             class => 'Rose::DB::Object::MakeMethods::Generic',
75             type => 'objects_by_key',
76             interface => 'get_set',
77             },
78              
79             get_set_now =>
80             {
81             class => 'Rose::DB::Object::MakeMethods::Generic',
82             type => 'objects_by_key',
83             interface => 'get_set_now',
84             },
85              
86             get_set_on_save =>
87             {
88             class => 'Rose::DB::Object::MakeMethods::Generic',
89             type => 'objects_by_key',
90             interface => 'get_set_on_save',
91             },
92              
93             add_now =>
94             {
95             class => 'Rose::DB::Object::MakeMethods::Generic',
96             type => 'objects_by_key',
97             interface => 'add_now',
98             },
99              
100             add_on_save =>
101             {
102             class => 'Rose::DB::Object::MakeMethods::Generic',
103             type => 'objects_by_key',
104             interface => 'add_on_save',
105             },
106             );
107              
108 8     8 1 97 sub type { 'one to many' }
109              
110 0     0 1 0 sub is_singular { 0 }
111              
112 0     0 0 0 sub foreign_class { shift->class(@_) }
113              
114             *map_column = \&key_column;
115             *column_map = \&key_columns;
116              
117             sub id
118             {
119 12     12 0 19 my($self) = shift;
120              
121 12         25 my $column_map = $self->column_map;
122              
123             return $self->parent->class . ' ' . $self->class . ' ' .
124 12         73 join("\0", map { join("\1", lc $_, lc $column_map->{$_}) } sort keys %$column_map);
  12         56  
125             #join("\0", map { $_ . '=' . ($self->$_() || 0) } qw(required));
126             }
127              
128             sub build_method_name_for_type
129             {
130 12     12 1 36 my($self, $type) = @_;
131              
132 12 100 33     79 if($type eq 'get_set' || $type eq 'get_set_now' || $type eq 'get_set_on_save')
    100 66        
    50 66        
    0          
    0          
133             {
134 4         16 return $self->name;
135             }
136             elsif($type eq 'add_now' || $type eq 'add_on_save')
137             {
138 4         27 return 'add_' . $self->name;
139             }
140             elsif($type eq 'find')
141             {
142 4         21 return 'find_' . $self->name;
143             }
144             elsif($type eq 'iterator')
145             {
146 0         0 return $self->name . '_iterator';
147             }
148             elsif($type eq 'count')
149             {
150 0         0 return $self->name . '_count';
151             }
152              
153 0         0 return undef;
154             }
155              
156             sub is_ready_to_make_methods
157             {
158 4     4 0 9 my($self) = shift;
159              
160 4 50 33     22 if($Debug || $Rose::DB::Object::Metadata::Debug)
161             {
162 0         0 my $error;
163              
164 0 0 0     0 if(!$self->class)
    0          
165             {
166 0         0 $error = "does not belong to a class";
167             }
168             elsif(!$self->key_columns && !$self->query_args)
169             {
170 0         0 $error = "has no key columns or query args";
171             }
172              
173 0 0       0 warn $self->parent->class, ': one-to-many relationship ', $self->name, " NOT READY - $error"
174             if($error);
175             }
176              
177 4 50 33     23 return $self->class && ($self->key_columns || $self->query_args) ? 1 : 0;
178             }
179              
180             1;
181              
182             __END__
183              
184             =head1 NAME
185              
186             Rose::DB::Object::Metadata::Relationship::OneToMany - One to many table relationship metadata object.
187              
188             =head1 SYNOPSIS
189              
190             use Rose::DB::Object::Metadata::Relationship::OneToMany;
191              
192             $rel = Rose::DB::Object::Metadata::Relationship::OneToMany->new(...);
193             $rel->make_methods(...);
194             ...
195              
196             =head1 DESCRIPTION
197              
198             Objects of this class store and manipulate metadata for relationships in which a single row from one table refers to multiple rows in another table.
199              
200             This class inherits from L<Rose::DB::Object::Metadata::Relationship>. Inherited methods that are not overridden will not be documented a second time here. See the L<Rose::DB::Object::Metadata::Relationship> documentation for more information.
201              
202             =head1 METHOD MAP
203              
204             =over 4
205              
206             =item C<count>
207              
208             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>, C<interface =E<gt> 'count'> ...
209              
210             =item C<find>
211              
212             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>, C<interface =E<gt> 'find'> ...
213              
214             =item C<iterator>
215              
216             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>, C<interface =E<gt> 'iterator'> ...
217              
218             =item C<get_set>
219              
220             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>,
221             C<interface =E<gt> 'get_set'> ...
222              
223             =item C<get_set_now>
224              
225             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>, C<interface =E<gt> 'get_set_now'> ...
226              
227             =item C<get_set_on_save>
228              
229             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>, C<interface =E<gt> 'get_set_on_save'> ...
230              
231             =item C<add_now>
232              
233             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>, C<interface =E<gt> 'add_now'> ...
234              
235             =item C<add_on_save>
236              
237             L<Rose::DB::Object::MakeMethods::Generic>, L<objects_by_key|Rose::DB::Object::MakeMethods::Generic/objects_by_key>, C<interface =E<gt> 'add_on_save'> ...
238              
239             =back
240              
241             See the L<Rose::DB::Object::Metadata::Relationship|Rose::DB::Object::Metadata::Relationship/"MAKING METHODS"> documentation for an explanation of this method map.
242              
243             =head1 CLASS METHODS
244              
245             =over 4
246              
247             =item B<default_auto_method_types [TYPES]>
248              
249             Get or set the default list of L<auto_method_types|Rose::DB::Object::Metadata::Relationship/auto_method_types>. TYPES should be a list of relationship method types. Returns the list of default relationship method types (in list context) or a reference to an array of the default relationship method types (in scalar context). The default list contains "find", "get_set_on_save", and "add_on_save".
250              
251             =back
252              
253             =head1 OBJECT METHODS
254              
255             =over 4
256              
257             =item B<build_method_name_for_type TYPE>
258              
259             Return a method name for the relationship method type TYPE.
260              
261             For the method types "get_set", "get_set_now", and "get_set_on_save", the relationship's L<name|Rose::DB::Object::Metadata::Relationship/name> is returned.
262              
263             For the method types "add_now" and "add_on_save", the relationship's L<name|Rose::DB::Object::Metadata::Relationship/name> prefixed with "add_" is returned.
264              
265             For the method type "find", the relationship's L<name|Rose::DB::Object::Metadata::Relationship/name> prefixed with "find_" is returned.
266              
267             For the method type "count", the relationship's L<name|Rose::DB::Object::Metadata::Relationship/name> suffixed with "_count" is returned.
268              
269             For the method type "iterator", the relationship's L<name|Rose::DB::Object::Metadata::Relationship/name> suffixed with "_iterator" is returned.
270              
271             Otherwise, undef is returned.
272              
273             =item B<is_singular>
274              
275             Returns false.
276              
277             =item B<manager_class [CLASS]>
278              
279             Get or set the name of the L<Rose::DB::Object::Manager>-derived class used to fetch objects. The L<make_methods|Rose::DB::Object::Metadata::Relationship/make_methods> method will use L<Rose::DB::Object::Manager> if this value is left undefined.
280              
281             B<Note:> when the name of a relationship that has C<manager_args> is used in a L<Rose::DB::Object::Manager> L<with_objects|Rose::DB::Object::Manager/with_objects> or L<require_objects|Rose::DB::Object::Manager/require_objects> parameter value, I<only> the L<sort_by|Rose::DB::Object::Manager/sort_by> argument will be copied from C<manager_args> and incorporated into the query.
282              
283             =item B<manager_method [METHOD]>
284              
285             Get or set the name of the L<manager_class|/manager_class> class method to call when fetching objects. The L<make_methods|Rose::DB::Object::Metadata::Relationship/make_methods> method will use L<get_objects|Rose::DB::Object::Manager/get_objects> if this value is left undefined.
286              
287             =item B<manager_count_method [METHOD]>
288              
289             Get or set the name of the L<manager_class|/manager_class> class method to call when counting objects. The L<make_methods|Rose::DB::Object::Metadata::Relationship/make_methods> method will use L<get_objects_count|Rose::DB::Object::Manager/get_objects_count> if this value is left undefined.
290              
291             =item B<manager_iterator_method [METHOD]>
292              
293             Get or set the name of the L<manager_class|/manager_class> class method to call when creating an iterator. The L<make_methods|Rose::DB::Object::Metadata::Relationship/make_methods> method will use L<get_objects_iterator|Rose::DB::Object::Manager/get_objects_iterator> if this value is left undefined.
294              
295             =item B<manager_args [HASHREF]>
296              
297             Get or set a reference to a hash of name/value arguments to pass to the L<manager_method|/manager_method> when fetching objects. For example, this can be used to enforce a particular sort order for objects fetched via this relationship. For example:
298              
299             Product->meta->add_relationship
300             (
301             code_names =>
302             {
303             type => 'one to many',
304             class => 'CodeName',
305             column_map => { id => 'product_id' },
306             manager_args =>
307             {
308             sort_by => CodeName->meta->table . '.name',
309             },
310             },
311             );
312              
313             This would ensure that a C<Product>'s C<code_names()> are listed in alphabetical order. Note that the "name" column is prefixed by the name of the table fronted by the C<CodeName> class. This is important because several tables may have a column named "name." If this relationship is used to form a JOIN in a query along with one of those tables, then the "name" column will be ambiguous. Adding a table name prefix disambiguates the column name.
314              
315             Also note that the table name is not hard-coded. Instead, it is fetched from the L<Rose::DB::Object>-derived class that fronts the table. This is more verbose, but is a much better choice than including the literal table name when it comes to long-term maintenance of the code.
316              
317             See the documentation for L<Rose::DB::Object::Manager>'s L<get_objects|Rose::DB::Object::Manager/get_objects> method for a full list of valid arguments for use with the C<manager_args> parameter, but remember that you can define your own custom L<manager_class|/manager_class> and thus can also define what kinds of arguments C<manager_args> will accept.
318              
319             =item B<map_column LOCAL [, FOREIGN]>
320              
321             If passed a local column name LOCAL, return the corresponding column name in the foreign table. If passed both a local column name LOCAL and a foreign column name FOREIGN, set the local/foreign mapping and return the foreign column name.
322              
323             =item B<column_map [HASH | HASHREF]>
324              
325             Get or set a reference to a hash that maps local column names to foreign column names.
326              
327             =item B<query_args [ARRAYREF]>
328              
329             Get or set a reference to an array of query arguments to add to the L<query|Rose::DB::Object::Manager/query> passed to the L<manager_method|/manager_method> when fetching objects.
330              
331             =item B<type>
332              
333             Returns "one to many".
334              
335             =back
336              
337             =head1 AUTHOR
338              
339             John C. Siracusa (siracusa@gmail.com)
340              
341             =head1 LICENSE
342              
343             Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is
344             free software; you can redistribute it and/or modify it under the same terms
345             as Perl itself.