File Coverage

blib/lib/Rose/DB/Object/Metadata/ForeignKey.pm
Criterion Covered Total %
statement 79 158 50.0
branch 25 82 30.4
condition 9 33 27.2
subroutine 20 33 60.6
pod 6 22 27.2
total 139 328 42.3


line stmt bran cond sub pod time code
1             package Rose::DB::Object::Metadata::ForeignKey;
2              
3 61     61   430 use strict;
  61         176  
  61         2135  
4              
5 61     61   356 use Carp();
  61         157  
  61         830  
6 61     61   290 use Scalar::Util();
  61         131  
  61         1445  
7              
8 61     61   29129 use Rose::DB::Object::Metadata::Util qw(:all);
  61         773  
  61         10018  
9              
10 61     61   43787 use Rose::DB::Object::Metadata::Column;
  61         238  
  61         4218  
11             our @ISA = qw(Rose::DB::Object::Metadata::Column);
12              
13 61     61   38664 use Rose::DB::Object::Exception;
  61         183  
  61         5608  
14              
15             our $VERSION = '0.784';
16              
17             our $Debug = 0;
18              
19             use overload
20             (
21             # "Undo" inherited overloaded stringification.
22             # (Using "no overload ..." didn't seem to work.)
23 2144     2144   8887 '""' => sub { overload::StrVal($_[0]) },
24 61         450 fallback => 1,
25 61     61   512 );
  61         168  
26              
27             __PACKAGE__->default_auto_method_types(qw(get_set_on_save delete_on_save));
28              
29             __PACKAGE__->add_common_method_maker_argument_names
30             (
31             qw(hash_key share_db class key_columns foreign_key referential_integrity)
32             );
33              
34             use Rose::Object::MakeMethods::Generic
35             (
36 61         649 boolean =>
37             [
38             'share_db' => { default => 1 },
39             'referential_integrity' => { default => 1 },
40             'with_column_triggers' => { default => 0 },
41             'disable_column_triggers',
42             ],
43              
44             scalar => 'deferred_make_method_args',
45              
46             hash =>
47             [
48             _key_column => { hash_key => '_key_columns' },
49             _key_columns => { interface => 'get_set_all' },
50             ],
51 61     61   7344 );
  61         167  
52              
53 0     0 0 0 sub is_singular { 1 }
54              
55 0     0 0 0 sub foreign_class { shift->class(@_) }
56              
57             sub key_column
58             {
59 0     0 1 0 my($self) = shift;
60              
61 0 0       0 if(@_ > 1)
62             {
63 0         0 $self->{'is_required'} = undef;
64             }
65              
66 0         0 return $self->_key_column(@_);
67             }
68              
69             sub key_columns
70             {
71 1114     1114 1 6198 my($self) = shift;
72              
73 1114 100       1794 if(@_)
74             {
75 32         69 $self->{'is_required'} = undef;
76             }
77              
78 1114         2211 return $self->_key_columns(@_);
79             }
80              
81             *column_map = \&key_columns;
82              
83             Rose::Object::MakeMethods::Generic->make_methods
84             (
85             { preserve_existing => 1 },
86             scalar =>
87             [
88             __PACKAGE__->common_method_maker_argument_names,
89             relationship_type => { interface => 'get_set_init' },
90             ],
91             );
92              
93             *rel_type = \&relationship_type;
94              
95             __PACKAGE__->method_maker_info
96             (
97             get_set =>
98             {
99             class => 'Rose::DB::Object::MakeMethods::Generic',
100             type => 'object_by_key',
101             interface => 'get_set',
102             },
103              
104             get_set_now =>
105             {
106             class => 'Rose::DB::Object::MakeMethods::Generic',
107             type => 'object_by_key',
108             interface => 'get_set_now',
109             },
110              
111             get_set_on_save =>
112             {
113             class => 'Rose::DB::Object::MakeMethods::Generic',
114             type => 'object_by_key',
115             interface => 'get_set_on_save',
116             },
117              
118             delete_now =>
119             {
120             class => 'Rose::DB::Object::MakeMethods::Generic',
121             type => 'object_by_key',
122             interface => 'delete_now',
123             },
124              
125             delete_on_save =>
126             {
127             class => 'Rose::DB::Object::MakeMethods::Generic',
128             type => 'object_by_key',
129             interface => 'delete_on_save',
130             },
131             );
132              
133 32     32 0 268 sub init_relationship_type { 'many to one' }
134              
135 208     208 0 395 sub foreign_key { $_[0] }
136              
137 312     312 1 1042 sub type { 'foreign key' }
138              
139             sub soft
140             {
141 0     0 1 0 my($self) = shift;
142              
143 0 0       0 if(@_)
144             {
145 0         0 $self->referential_integrity(!$_[0]);
146             }
147              
148 0         0 return ! $self->referential_integrity;
149             }
150              
151             sub is_required
152             {
153 52     52 0 72 my($self) = shift;
154              
155 52 50       134 return $self->{'required'} if(defined $self->{'required'});
156 52 100       148 return $self->{'is_required'} if(defined $self->{'is_required'});
157              
158 32 50       92 my $meta = $self->parent or
159             Carp::croak "Missing parent for foreign key '", $self->name, "'";
160              
161 32         89 my $key_columns = $self->key_columns;
162              
163             # If any local key column allows null values, then
164             # the foreign object is not required.
165 32         236 foreach my $column_name (keys %$key_columns)
166             {
167 32 50       87 my $column = $meta->column($column_name)
168             or Carp::confess "No such column '$column_name' in table '",
169             $self->parent->table, "' referenced from foreign key '",
170             $self->name, "'";
171              
172 32 50       107 unless($column->not_null)
173             {
174 32         193 return $self->{'is_required'} = 0;
175             }
176             }
177              
178 0         0 return $self->{'is_required'} = 1;
179             }
180              
181             sub make_methods
182             {
183 52     52 1 114 my($self) = shift;
184 52         182 $self->is_required; # initialize
185 52         211 $self->SUPER::make_methods(@_);
186              
187 52 50       190 if($self->with_column_triggers)
188             {
189 0   0     0 my $method = $self->method_name('get_set_on_save') ||
190             $self->method_name('get_set');
191              
192 0 0       0 if($method)
193             {
194 0 0       0 my $meta = $self->parent or
195             Carp::croak "Missing parent for foreign key '", $self->name, "'";
196              
197 0         0 my $key_columns = $self->key_columns;
198              
199 0         0 foreach my $column_name (keys %$key_columns)
200             {
201 0         0 my $column = $meta->column($column_name);
202 0         0 my $accessor = $column->accessor_method_name;
203 0         0 my $trigger_name = 'clear_fk' . $self->name;
204              
205 0 0       0 unless(defined $column->builtin_trigger_index('on_set', $trigger_name))
206             {
207 0         0 my $wolumn = Scalar::Util::weaken($column);
208              
209             $column->add_builtin_trigger(
210             event => 'on_set',
211             name => $trigger_name,
212             code => sub
213             {
214 0     0   0 my($obj) = shift;
215 0 0       0 return if($self->{'disable_column_triggers'});
216 0         0 local $wolumn->{'triggers_disabled'} = 1;
217 0 0       0 $obj->$method(undef) unless(defined $obj->$accessor());
218 0         0 });
219             }
220             }
221             }
222             }
223             }
224              
225             sub build_method_name_for_type
226             {
227 64     64 1 112 my($self, $type) = @_;
228              
229 64 100 33     396 if($type eq 'get_set' || $type eq 'get_set_now' || $type eq 'get_set_on_save')
    50 66        
      33        
230             {
231 32         107 return $self->name;
232             }
233             elsif($type eq 'delete_now' || $type eq 'delete_on_save')
234             {
235 32         104 return 'delete_' . $self->name;
236             }
237              
238 0         0 return undef;
239             }
240              
241             sub id
242             {
243 250     250 0 402 my($self) = shift;
244              
245 250         489 my $key_columns = $self->key_columns;
246              
247             return $self->parent->class . ' ' . $self->class . ' ' .
248 250         1397 join("\0", map { join("\1", lc $_, lc $key_columns->{$_}) } sort keys %$key_columns) .
  250         945  
249             #join("\0", map { $_ . '=' . ($self->$_() || 0) } qw(...));
250             'required=' . $self->referential_integrity;
251             }
252              
253             sub sanity_check
254             {
255 112     112 0 150 my($self) = shift;
256              
257 112         238 my $key_columns = $self->key_columns;
258              
259 61     61   118124 no warnings;
  61         178  
  61         79399  
260 112 50 33     914 unless(ref $key_columns eq 'HASH' && keys %$key_columns)
261             {
262             #Carp::croak "Foreign key '", $self->name, "' is missing a key_columns";
263 0         0 return;
264             }
265              
266 112         253 return 1;
267             }
268              
269             sub is_ready_to_make_methods
270             {
271 100     100 0 172 my($self) = shift;
272              
273 100 50       197 return 0 unless($self->sanity_check);
274              
275 100         151 my $error;
276              
277             TRY:
278             {
279 100         127 local $@;
  100         157  
280              
281             eval
282 100         176 {
283             # Workaround for http://rt.perl.org/rt3/Ticket/Display.html?id=60890
284 100         326 local $SIG{'__DIE__'};
285              
286 100 50       449 $self->class->isa('Rose::DB::Object') or die
287             Rose::DB::Object::Exception::ClassNotReady->new(
288             "Missing or invalid foreign class");
289              
290 100 50       322 my $fk_meta = $self->class->meta or die
291             Rose::DB::Object::Exception::ClassNotReady->new(
292             "Missing meta object for " . $self->class);
293              
294 100   50     186 my $key_columns = $self->key_columns || {};
295              
296 100         624 foreach my $column_name (values %$key_columns)
297             {
298 100 50       274 unless($fk_meta->column($column_name))
299             {
300 0         0 die Rose::DB::Object::Exception::ClassNotReady->new(
301             "No column '$column_name' in class " . $fk_meta->class);
302             }
303              
304 100 100 66     306 unless($fk_meta->column_accessor_method_name($column_name) &&
305             $fk_meta->column_mutator_method_name($column_name))
306             {
307 48         179 die Rose::DB::Object::Exception::ClassNotReady->new(
308             "Foreign class not initialized");
309             }
310             }
311             };
312              
313 100         812 $error = $@;
314             }
315              
316 100 100       269 if($error)
317             {
318 48 50 33     162 if($Debug || $Rose::DB::Object::Metadata::Debug)
319             {
320 0         0 my $err = $error;
321 0         0 $err =~ s/ at .*//;
322 0         0 warn $self->parent->class, ': Foreign key ', $self->name, " NOT READY - $err";
323             }
324              
325 48 50       181 die $error unless(UNIVERSAL::isa($error, 'Rose::DB::Object::Exception::ClassNotReady'));
326             }
327              
328 100 100       276 return $error ? 0 : 1;
329             }
330              
331             our $DEFAULT_INLINE_LIMIT = 80;
332              
333             sub perl_hash_definition
334             {
335 0     0 0   my($self, %args) = @_;
336              
337 0           my $meta = $self->parent;
338              
339 0 0         my $indent = defined $args{'indent'} ? $args{'indent'} :
    0          
340             ($meta ? $meta->default_perl_indent : undef);
341              
342 0 0         my $braces = defined $args{'braces'} ? $args{'braces'} :
    0          
343             ($meta ? $meta->default_perl_braces : undef);
344              
345 0 0         my $inline = defined $args{'inline'} ? $args{'inline'} : 0;
346 0 0         my $inline_limit = defined $args{'inline'} ? $args{'inline_limit'} : $DEFAULT_INLINE_LIMIT;
347              
348 0           my $name_padding = $args{'name_padding'};
349              
350 0           my %attrs = map { $_ => 1 } $self->perl_foreign_key_definition_attributes;
  0            
351 0           my %hash = $self->spec_hash;
352              
353 0           my @delete_keys = grep { !$attrs{$_} } keys %hash;
  0            
354 0           delete @hash{@delete_keys};
355              
356 0           my $key_columns = $self->key_columns;
357              
358             # Only inline single-pair key column mappings
359 0 0         if(keys %$key_columns > 1)
360             {
361 0           $inline_limit = 1;
362 0           $inline = 0;
363             }
364              
365 0           my $max_len = 0;
366 0           my $min_len = -1;
367              
368 0           foreach my $name (keys %hash)
369             {
370 0 0         $max_len = length($name) if(length $name > $max_len);
371 0 0 0       $min_len = length($name) if(length $name < $min_len || $min_len < 0);
372             }
373              
374 0 0 0       if(defined $name_padding && $name_padding > 0)
375             {
376 0           return sprintf('%-*s => ', $name_padding, perl_quote_key($self->name)) .
377             perl_hashref(hash => \%hash,
378             braces => $braces,
379             inline => $inline,
380             inline_limit => $inline_limit,
381             indent => $indent,
382             key_padding => hash_key_padding(\%hash));
383             }
384             else
385             {
386 0           return perl_quote_key($self->name) . ' => ' .
387             perl_hashref(hash => \%hash,
388             braces => $braces,
389             inline => $inline,
390             inline_limit => $inline_limit,
391             indent => $indent,
392             key_padding => hash_key_padding(\%hash));
393             }
394             }
395              
396 0     0 0   sub perl_foreign_key_definition_attributes { qw(class key_columns soft rel_type) }
397              
398             # Some object keys have different names when they appear
399             # in hashref-style foreign key specs. This hash maps
400             # between the two in the case where they differ.
401             sub spec_hash_map
402             {
403             {
404             # object key spec key
405 0     0 0   method_name => 'methods',
406             _key_columns => 'key_columns',
407             relationship_type => 'rel_type',
408             }
409             }
410              
411             # Return a hashref-style foreign key spec
412             sub spec_hash
413             {
414 0     0 0   my($self) = shift;
415              
416 0   0       my $map = $self->spec_hash_map || {};
417              
418 0           my %spec;
419              
420 0           foreach my $key (keys(%$self))
421             {
422 0 0         if(exists $map->{$key})
423             {
424 0 0         my $spec_key = $map->{$key} or next;
425 0           $spec{$spec_key} = $self->{$key};
426             }
427             else
428             {
429 0           $spec{$key} = $self->{$key};
430             }
431             }
432              
433             # Don't include this key if it has the default value. Anal, I know...
434 0 0         delete $spec{'rel_type'} if($spec{'rel_type'} eq $self->init_relationship_type);
435              
436 0 0         return wantarray ? %spec : \%spec;
437             }
438              
439             sub object_has_foreign_object
440             {
441 0     0 0   my($self, $object) = @_;
442              
443 0 0         unless($object->isa($self->parent->class))
444             {
445 0           my $class = $self->parent->class;
446 0           Carp::croak "Cannot check for foreign object related through the ", $self->name,
447             " foreign key. Object does not inherit from $class: $object";
448             }
449              
450 0   0       return $object->{$self->hash_key} || 0;
451             }
452              
453 0     0 0   sub hash_keys_used { shift->hash_key }
454              
455             sub forget_foreign_object
456             {
457 0     0 0   my($self, $object) = @_;
458              
459 0           foreach my $key ($self->hash_keys_used)
460             {
461 0           $object->{$key} = undef;
462             }
463             }
464              
465 0     0 0   sub requires_preexisting_parent_object { 0 }
466              
467             1;
468              
469             __END__
470              
471             =head1 NAME
472              
473             Rose::DB::Object::Metadata::ForeignKey - Foreign key metadata.
474              
475             =head1 SYNOPSIS
476              
477             use Rose::DB::Object::Metadata::ForeignKey;
478              
479             $fk = Rose::DB::Object::Metadata::ForeignKey->new(...);
480             $fk->make_methods(...);
481             ...
482              
483             =head1 DESCRIPTION
484              
485             Objects of this class store and manipulate metadata for foreign keys in a database table. It stores information about which columns in the local table map to which columns in the foreign table.
486              
487             This class will create methods for C<the thing referenced by> the foreign key column(s). You'll still need accessor method(s) for the foreign key column(s) themselves.
488              
489             Both the local table and the foreign table must have L<Rose::DB::Object>-derived classes fronting them.
490              
491             Foreign keys can represent both "L<one to one|Rose::DB::Object::Metadata::Relationship::OneToOne>" and "L<many to one|Rose::DB::Object::Metadata::Relationship::ManyToOne>" relationships. To choose, set the L<relationship_type|/relationship_type> attribute to either "one to one" or "many to one". The default is "many to one".
492              
493             =head2 MAKING METHODS
494              
495             A L<Rose::DB::Object::Metadata::ForeignKey>-derived object is responsible for creating object methods that manipulate objects referenced by a foreign key. Each foreign key object can make zero or more methods for each available foreign key method type. A foreign key method type describes the purpose of a method. The default list of foreign key method types contains only one type:
496              
497             =over 4
498              
499             =item C<get_set>
500              
501             A method that returns the object referenced by the foreign key.
502              
503             =back
504              
505             Methods are created by calling L<make_methods|/make_methods>. A list of method types can be passed to the call to L<make_methods|/make_methods>. If absent, the list of method types is determined by the L<auto_method_types|/auto_method_types> method. A list of all possible method types is available through the L<available_method_types|/available_method_types> method.
506              
507             These methods make up the "public" interface to foreign key method creation. There are, however, several "protected" methods which are used internally to implement the methods described above. (The word "protected" is used here in a vaguely C++ sense, meaning "accessible to subclasses, but not to the public.") Subclasses will probably find it easier to override and/or call these protected methods in order to influence the behavior of the "public" method maker methods.
508              
509             A L<Rose::DB::Object::Metadata::ForeignKey> object delegates method creation to a L<Rose::Object::MakeMethods>-derived class. Each L<Rose::Object::MakeMethods>-derived class has its own set of method types, each of which takes it own set of arguments.
510              
511             Using this system, four pieces of information are needed to create a method on behalf of a L<Rose::DB::Object::Metadata::ForeignKey>-derived object:
512              
513             =over 4
514              
515             =item * The B<foreign key method type> (e.g., C<get_set>)
516              
517             =item * The B<method maker class> (e.g., L<Rose::DB::Object::MakeMethods::Generic>)
518              
519             =item * The B<method maker method type> (e.g., L<object_by_key|Rose::DB::Object::MakeMethods::Generic/object_by_key>)
520              
521             =item * The B<method maker arguments> (e.g., C<interface =E<gt> 'get_set'>)
522              
523             =back
524              
525             This information can be organized conceptually into a "method map" that connects a foreign key method type to a method maker class and, finally, to one particular method type within that class, and its arguments.
526              
527             The default method map for L<Rose::DB::Object::Metadata::ForeignKey> is:
528              
529             =over 4
530              
531             =item C<get_set>
532              
533             L<Rose::DB::Object::MakeMethods::Generic>, L<object_by_key|Rose::DB::Object::MakeMethods::Generic/object_by_key>,
534             C<interface =E<gt> 'get_set'> ...
535              
536             =item C<get_set_now>
537              
538             L<Rose::DB::Object::MakeMethods::Generic>, L<object_by_key|Rose::DB::Object::MakeMethods::Generic/object_by_key>, C<interface =E<gt> 'get_set_now'> ...
539              
540             =item C<get_set_on_save>
541              
542             L<Rose::DB::Object::MakeMethods::Generic>, L<object_by_key|Rose::DB::Object::MakeMethods::Generic/object_by_key>, C<interface =E<gt> 'get_set_on_save'> ...
543              
544             =item C<delete_now>
545              
546             L<Rose::DB::Object::MakeMethods::Generic>, L<object_by_key|Rose::DB::Object::MakeMethods::Generic/object_by_key>, C<interface =E<gt> 'delete_now'> ...
547              
548             =item C<delete_on_save>
549              
550             L<Rose::DB::Object::MakeMethods::Generic>, L<object_by_key|Rose::DB::Object::MakeMethods::Generic/object_by_key>, C<interface =E<gt> 'delete_on_save'> ...
551              
552             =back
553              
554             Each item in the map is a foreign key method type. For each foreign key method type, the method maker class, the method maker method type, and the "interesting" method maker arguments are listed, in that order.
555              
556             The "..." in the method maker arguments is meant to indicate that arguments have been omitted. Arguments that are common to all foreign key method types are routinely omitted from the method map for the sake of brevity.
557              
558             The purpose of documenting the method map is to answer the question, "What kind of method(s) will be created by this foreign key object for a given method type?" Given the method map, it's possible to read the documentation for each method maker class to determine how methods of the specified type behave when passed the listed arguments.
559              
560             Remember, the existence and behavior of the method map is really implementation detail. A foreign key object is free to implement the public method-making interface however it wants, without regard to any conceptual or actual method map.
561              
562             =head1 CLASS METHODS
563              
564             =over 4
565              
566             =item B<default_auto_method_types [TYPES]>
567              
568             Get or set the default list of L<auto_method_types|/auto_method_types>. TYPES should be a list of foreign key method types. Returns the list of default foreign key method types (in list context) or a reference to an array of the default foreign key method types (in scalar context). The default list contains the "get_set_on_save" and "delete_on_save" foreign key method types.
569              
570             =back
571              
572             =head1 OBJECT METHODS
573              
574             =over 4
575              
576             =item B<available_method_types>
577              
578             Returns the full list of foreign key method types supported by this class.
579              
580             =item B<auto_method_types [TYPES]>
581              
582             Get or set the list of foreign key method types that are automatically created when L<make_methods|/make_methods> is called without an explicit list of foreign key method types. The default list is determined by the L<default_auto_method_types|/default_auto_method_types> class method.
583              
584             =item B<build_method_name_for_type TYPE>
585              
586             Return a method name for the foreign key method type TYPE. The default implementation returns the following.
587              
588             For the method types "get_set", "get_set_now", and "get_set_on_save", the foreign key's L<name|/name> is returned.
589              
590             For the method types "delete_now" and "delete_on_save", the foreign key's L<name|/name> prefixed with "delete_" is returned.
591              
592             Otherwise, undef is returned.
593              
594             =item B<class [CLASS]>
595              
596             Get or set the class name of the L<Rose::DB::Object>-derived object that encapsulates rows from the table referenced by the foreign key column(s).
597              
598             =item B<column_map [HASH | HASHREF]>
599              
600             This is an alias for the L<key_columns|/key_columns> method.
601              
602             =item B<key_column LOCAL [, FOREIGN]>
603              
604             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.
605              
606             =item B<key_columns [ HASH | HASHREF ]>
607              
608             Get or set a hash that maps local column names to foreign column names in the table referenced by the foreign key. Returns a reference to a hash in scalar context, or a list of key/value pairs in list context.
609              
610             =item B<make_methods PARAMS>
611              
612             Create object method used to manipulate object referenced by the foreign key. Any applicable L<column triggers|/with_column_triggers> are also added. PARAMS are name/value pairs. Valid PARAMS are:
613              
614             =over 4
615              
616             =item C<preserve_existing BOOL>
617              
618             Boolean flag that indicates whether or not to preserve existing methods in the case of a name conflict.
619              
620             =item C<replace_existing BOOL>
621              
622             Boolean flag that indicates whether or not to replace existing methods in the case of a name conflict.
623              
624             =item C<target_class CLASS>
625              
626             The class in which to make the method(s). If omitted, it defaults to the calling class.
627              
628             =item C<types ARRAYREF>
629              
630             A reference to an array of foreign key method types to be created. If omitted, it defaults to the list of foreign key method types returned by L<auto_method_types|/auto_method_types>.
631              
632             =back
633              
634             If any of the methods could not be created for any reason, a fatal error will occur.
635              
636             =item B<methods MAP>
637              
638             Set the list of L<auto_method_types|/auto_method_types> and method names all at once. MAP should be a reference to a hash whose keys are method types and whose values are either undef or method names. If a value is undef, then the method name for that method type will be generated by calling B<build_method_name_for_type|/build_method_name_for_type>, as usual. Otherwise, the specified method name will be used.
639              
640             =item B<method_name TYPE [, NAME]>
641              
642             Get or set the name of the relationship method of type TYPE.
643              
644             =item B<method_types [TYPES]>
645              
646             This method is an alias for the L<auto_method_types|/auto_method_types> method.
647              
648             =item B<name [NAME]>
649              
650             Get or set the name of the foreign key. This name must be unique among all other foreign keys for a given L<Rose::DB::Object>-derived class.
651              
652             =item B<referential_integrity [BOOL]>
653              
654             Get or set the boolean value that determines what happens when the local L<key columns|/key_columns> have L<defined|perlfunc/defined> values, but the object they point to is not found. If true, a fatal error will occur when the methods that fetch objects through this foreign key are called. If false, then the methods will simply return undef. The default is true.
655              
656             =item B<rel_type [TYPE]>
657              
658             This method is an alias for the L<relationship_type|/relationship_type> method described below.
659              
660             =item B<relationship_type [TYPE]>
661              
662             Get or set the relationship type represented by this foreign key. Valid values for TYPE are "L<one to one|Rose::DB::Object::Metadata::Relationship::OneToOne>" and "L<many to one|Rose::DB::Object::Metadata::Relationship::ManyToOne>".
663              
664             =item B<share_db [BOOL]>
665              
666             Get or set the boolean flag that determines whether the L<db|Rose::DB::Object/db> attribute of the current object is shared with the foreign object to be fetched. The default value is true.
667              
668             =item B<soft [BOOL]>
669              
670             This method is the mirror image of the L<referential_integrity|/referential_integrity> method. Passing a true is the same thing as setting L<referential_integrity|/referential_integrity> to false, and vice versa. Similarly, the return value is the logical negation of L<referential_integrity|/referential_integrity>.
671              
672             =item B<type>
673              
674             Returns "foreign key".
675              
676             =item B<with_column_triggers [BOOL]>
677              
678             Get or set a boolean value that indicates whether or not L<triggers|Rose::DB::Object::Metadata::Column/TRIGGERS> should be added to the L<key columns|/key_columns> in an attempt to keep foreign objects and foreign key columns in sync. Defaults to false.
679              
680             =back
681              
682             =head1 PROTECTED API
683              
684             These methods are not part of the public interface, but are supported for use by subclasses. Put another way, given an unknown object that "isa" L<Rose::DB::Object::Metadata::ForeignKey>, there should be no expectation that the following methods exist. But subclasses, which know the exact class from which they inherit, are free to use these methods in order to implement the public API described above.
685              
686             =over 4
687              
688             =item B<method_maker_arguments TYPE>
689              
690             Returns a hash (in list context) or reference to a hash (in scalar context) of name/value arguments that will be passed to the L<method_maker_class|/method_maker_class> when making the foreign key method type TYPE.
691              
692             =item B<method_maker_class TYPE [, CLASS]>
693              
694             If CLASS is passed, the name of the L<Rose::Object::MakeMethods>-derived class used to create the object method of type TYPE is set to CLASS.
695              
696             Returns the name of the L<Rose::Object::MakeMethods>-derived class used to create the object method of type TYPE.
697              
698             =item B<method_maker_type TYPE [, NAME]>
699              
700             If NAME is passed, the name of the method maker method type for the foreign key method type TYPE is set to NAME.
701              
702             Returns the method maker method type for the foreign key method type TYPE.
703              
704             =back
705              
706             =head1 AUTHOR
707              
708             John C. Siracusa (siracusa@gmail.com)
709              
710             =head1 LICENSE
711              
712             Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is
713             free software; you can redistribute it and/or modify it under the same terms
714             as Perl itself.