File Coverage

blib/lib/Rose/DB/Object/Metadata/Column.pm
Criterion Covered Total %
statement 308 613 50.2
branch 95 338 28.1
condition 43 220 19.5
subroutine 72 95 75.7
pod 24 58 41.3
total 542 1324 40.9


line stmt bran cond sub pod time code
1             package Rose::DB::Object::Metadata::Column;
2              
3 61     61   459 use strict;
  61         141  
  61         1820  
4              
5 61     61   335 use Carp();
  61         570  
  61         866  
6 61     61   310 use Scalar::Util();
  61         132  
  61         1256  
7              
8 61     61   336 use Rose::DB::Object::Metadata::Util qw(:all);
  61         158  
  61         7674  
9              
10 61     61   30210 use Rose::DB::Object::Metadata::MethodMaker;
  61         201  
  61         3611  
11             our @ISA = qw(Rose::DB::Object::Metadata::MethodMaker);
12              
13             use Rose::DB::Object::Util
14 61         4140 qw(column_value_formatted_key column_value_is_inflated_key
15 61     61   501 lazy_column_values_loaded_key);
  61         157  
16              
17             use Rose::DB::Object::Constants
18 61     61   424 qw(STATE_IN_DB STATE_LOADING STATE_SAVING SAVING_FOR_LOAD);
  61         141  
  61         3454  
19              
20 61     61   440 use Rose::Object::MakeMethods::Generic;
  61         147  
  61         332  
21 61     61   88347 use Rose::DB::Object::MakeMethods::Generic;
  61         220  
  61         695  
22              
23             our $Triggers_Key = 'triggers';
24             our $Trigger_Index_Key = 'trigger_index';
25              
26             our $VERSION = '0.791';
27              
28             use overload
29             (
30 11312     11312   20299 '""' => sub { shift->name },
31 61         881 fallback => 1,
32 61     61   7142 );
  61         163  
33              
34             __PACKAGE__->add_default_auto_method_types('get_set');
35              
36             __PACKAGE__->add_common_method_maker_argument_names(qw(column default type db_type hash_key smart_modification undef_overrides_default));
37              
38             use Rose::Class::MakeMethods::Generic
39             (
40 61         657 inheritable_scalar =>
41             [
42             'default_undef_overrides_default'
43             ],
44              
45             inheritable_hash =>
46             [
47             event_method_type => { hash_key => 'event_method_types' },
48             event_method_types => { interface => 'get_set_all' },
49             delete_event_method_type => { interface => 'delete', hash_key => 'event_method_types' },
50             ],
51 61     61   8633 );
  61         150  
52              
53             __PACKAGE__->event_method_types
54             (
55             inflate => [ qw(get_set get) ],
56             deflate => [ qw(get_set get) ],
57             on_load => [ qw(get_set set) ],
58             on_save => [ qw(get_set get) ],
59             on_set => [ qw(get_set set) ],
60             on_get => [ qw(get_set get) ],
61             lazy_load => [ qw(get_set get) ],
62             );
63              
64             Rose::Object::MakeMethods::Generic->make_methods
65             (
66             { preserve_existing => 1 },
67             boolean =>
68             [
69             'manager_uses_method',
70             'is_primary_key_member',
71             'not_null',
72             'triggers_disabled',
73             'smart_modification',
74             'nonpersistent',
75             ],
76              
77             scalar =>
78             [
79             'alias',
80             'error',
81             'ordinal_position',
82             'parse_error',
83             'remarks',
84             __PACKAGE__->common_method_maker_argument_names,
85             ],
86             );
87              
88             *sequence = \&default_value_sequence_name;
89             *primary_key = \&is_primary_key_member;
90              
91             __PACKAGE__->method_maker_info
92             (
93             get_set =>
94             {
95             class => 'Rose::DB::Object::MakeMethods::Generic',
96             type => 'scalar',
97             },
98              
99             get =>
100             {
101             class => 'Rose::DB::Object::MakeMethods::Generic',
102             type => 'scalar',
103             },
104              
105             set =>
106             {
107             class => 'Rose::DB::Object::MakeMethods::Generic',
108             type => 'scalar',
109             },
110             );
111              
112             sub undef_overrides_default
113             {
114 297     297 1 537 my($self) = shift;
115              
116 297 50       633 if(@_)
117             {
118 0 0       0 return $self->{'undef_overrides_default'} = $_[0] ? 1 : 0;
119             }
120              
121             return $self->{'undef_overrides_default'}
122 297 50       746 if(defined $self->{'undef_overrides_default'});
123              
124 297 50       961 my $parent_default = $self->parent ? $self->parent->column_undef_overrides_default : undef;
125              
126 297 50       8964 return defined $parent_default ? $parent_default : ref($self)->default_undef_overrides_default;
127             }
128              
129             sub validate_specification
130             {
131 194     194 0 377 my($self) = shift;
132              
133 194 0 33     609 if($self->not_null && $self->{'undef_overrides_default'})
134             {
135 0         0 $self->error('True value for not_null attribute conflicts with true value for undef_overrides_default attribute.');
136 0         0 return 0;
137             }
138              
139 194         1346 return 1;
140             }
141              
142 61     61   45996 use constant ANY_DB => "\0ANY_DB\0";
  61         188  
  61         94402  
143              
144             sub default_value_sequence_name
145             {
146 157     157 0 276 my($self) = shift;
147              
148 157         242 my $db;
149 157 50       690 $db = shift if(UNIVERSAL::isa($_[0], 'Rose::DB'));
150 157         569 my $parent = $self->parent;
151 157         296 my ($db_id, $error);
152              
153             # Sometimes data source are not set up yet when this method
154             # is called. Allow for failure, falling back to ANY_DB
155             TRY:
156             {
157 157         237 local $@;
  157         264  
158 157 50       313 eval { $db_id = $db ? $db->id : $parent ? $parent->init_db_id : ANY_DB };
  157 50       570  
159 157         362 $error = $@;
160             }
161              
162 157 50       362 $db_id = ANY_DB if ($error);
163              
164 157 50       833 return $self->{'default_value_sequence_name'}{$db_id} unless(@_);
165              
166 0         0 $self->{'default_value_sequence_name'}{$db_id} = shift;
167              
168 0 0 0     0 if($parent && $self->is_primary_key_member)
169             {
170 0   0     0 $parent->refresh_primary_key_sequence_names($db || $db_id);
171             }
172              
173 0         0 return $self->{'default_value_sequence_name'}{$db_id};
174             }
175              
176             # These methods rely on knowledge of the hash key used to make the
177             # methods for the common_method_maker_argument_names in the base
178             # class, Rose::DB::Object::Metadata::MethodMaker. Luckily, it's just
179             # the attribute name by default.
180 0     0 1 0 sub default_exists { exists $_[0]->{'default'} }
181 0     0 1 0 sub delete_default { delete $_[0]->{'default'} }
182              
183             sub db_value_hash_key
184             {
185 0     0 0 0 my($self) = shift;
186              
187 0 0       0 my $type = $self->method_name('set') ? 'set' : 'get_set';
188              
189 0 0       0 if($self->method_uses_formatted_key($type))
190             {
191 0         0 return column_value_formatted_key($self->hash_key);
192             }
193              
194 0         0 return $self->hash_key;
195             }
196              
197             sub available_method_types
198             {
199 72     72 1 148 my($class) = shift;
200              
201 72         225 my @types = $class->SUPER::available_method_types;
202              
203 72 100       216 @types = qw(get_set get set) unless(@types);
204              
205 72         226 return @types;
206             }
207              
208             sub accessor_method_name
209             {
210 821   33 821 1 3806 return $_[0]->{'accessor_method_name'} ||=
      66        
211             $_[0]->method_name('get') || $_[0]->method_name('get_set')
212             }
213              
214             sub mutator_method_name
215             {
216 757   33 757 1 2864 return $_[0]->{'mutator_method_name'} ||=
      66        
217             $_[0]->method_name('set') || $_[0]->method_name('get_set')
218             }
219              
220             sub rw_method_name
221             {
222 914   66 914 1 4107 return $_[0]->{'rw_method_name'} ||= $_[0]->method_name('get_set')
223             }
224              
225             sub build_method_name_for_type
226             {
227 194     194 1 376 my($self, $type) = @_;
228              
229 194   66     675 my $name = $self->alias || $self->name;
230 194         586 $name =~ s/\W/_/g;
231              
232 194 50       444 if($type eq 'get_set')
    0          
    0          
233             {
234 194         489 return $name
235             }
236             elsif($type eq 'set')
237             {
238 0         0 return "set_$name";
239             }
240             elsif($type eq 'get')
241             {
242 0         0 return "get_$name";
243             }
244              
245 0         0 return undef;
246             }
247              
248             sub made_method_type
249             {
250 297     297 0 768 my($self, $type, $name) = @_;
251              
252 297 100       910 if($type eq 'get_set')
    50          
    50          
253             {
254 193         440 $self->{'accessor_method_name'} = $name;
255 193         444 $self->{'mutator_method_name'} = $name;
256 193         430 $self->{'rw_method_name'} = $name;
257             }
258             elsif($type eq 'get')
259             {
260 0         0 $self->{'accessor_method_name'} = $name;
261             }
262             elsif($type eq 'set')
263             {
264 0         0 $self->{'mutator_method_name'} = $name;
265             }
266              
267 297         895 $self->{'made_method_types'}{$type} = 1;
268             }
269              
270             sub defined_method_types
271             {
272 298     298 0 562 my($self) = shift;
273 298   100     432 my @types = sort keys %{$self->{'made_method_types'} ||= {}};
  298         1459  
274 298 100       947 return wantarray ? @types : \@types;
275             }
276              
277             sub method_maker_arguments
278             {
279 297     297 1 597 my($self, $type) = @_;
280              
281 297         794 my $args = $self->SUPER::method_maker_arguments($type);
282              
283 297   66     1129 $args->{'interface'} ||= $type;
284              
285 297 50       3436 return wantarray ? %$args : $args;
286             }
287              
288 339     339 1 1273 sub type { 'scalar' }
289 594     594 1 1509 sub column { $_[0] }
290              
291 0     0 1 0 sub should_inline_value { 0 }
292 0     0 0 0 sub inline_value_sql { $_[1] }
293              
294             sub name
295             {
296 15096     15096 1 25992 my($self) = shift;
297              
298 15096 100       27943 if(@_)
299             {
300 251         770 $self->name_sql(undef);
301 251         668 $self->select_sql(undef);
302 251         712 return $self->{'name'} = shift;
303             }
304              
305 14845         43015 return $self->{'name'};
306             }
307              
308 891 100   891 0 3074 sub hash_key { $_[0]->alias || $_[0]->name }
309              
310             sub name_sql
311             {
312 251     251 0 394 my($self) = shift;
313              
314 251 50       530 if(my $db = shift)
315             {
316 0   0     0 return $self->{'name_sql'}{$db->{'driver'}} ||= $db->auto_quote_column_name($self->{'name'});
317             }
318             else
319             {
320 251         821 return $self->{'name'};
321             }
322             }
323              
324             # XXX: Still need a way to format `table`.`column`
325             sub select_sql
326             {
327 246     246 0 488 my($self, $db, $table) = @_;
328              
329 246 50       474 if($db)
330             {
331 0 0       0 if(defined $table)
332             {
333 0         0 $db->auto_quote_column_with_table($self->{'name'}, $table);
334             }
335             else
336             {
337 0   0     0 return $self->{'select_sql'}{$db->{'driver'}} ||= $db->auto_quote_column_name($self->{'name'});
338             }
339             }
340             else
341             {
342 246         446 return $self->{'name'};
343             }
344             }
345              
346 0     0 0 0 sub insert_placeholder_sql { '?' }
347 0     0 0 0 sub update_placeholder_sql { '?' }
348 0     0 0 0 sub query_placeholder_sql { '?' }
349              
350             # sub dbi_data_type { () }
351              
352 0     0 1 0 sub parse_value { $_[2] }
353 0     0 1 0 sub format_value { $_[2] }
354              
355             sub primary_key_position
356             {
357 82     82 1 178 my($self) = shift;
358              
359 82 50       274 $self->{'primary_key_position'} = shift if(@_);
360              
361 82 50       192 unless($self->is_primary_key_member)
362             {
363 0         0 return $self->{'primary_key_position'} = undef;
364             }
365              
366 82         584 return $self->{'primary_key_position'};
367             }
368              
369             # These constants are from the DBI documentation. Is there somewhere
370             # I can load these from?
371 61     61   558 use constant SQL_NO_NULLS => 0;
  61         203  
  61         4176  
372 61     61   501 use constant SQL_NULLABLE => 1;
  61         164  
  61         27903  
373              
374             sub init_with_dbi_column_info
375             {
376 0     0 0 0 my($self, $col_info) = @_;
377              
378             # We're doing this in Rose::DB::Object::Metadata::Auto now
379             #$self->parent->db->refine_dbi_column_info($col_info);
380              
381 0 0       0 if(defined $col_info->{'COLUMN_DEF'})
382             {
383 0         0 $self->default($col_info->{'COLUMN_DEF'});
384             }
385              
386 0 0       0 if($col_info->{'NULLABLE'} == SQL_NO_NULLS)
    0          
387             {
388 0         0 $self->not_null(1);
389             }
390             elsif($col_info->{'NULLABLE'} == SQL_NULLABLE)
391             {
392 0         0 $self->not_null(0);
393             }
394              
395             # DB-native type, if applicable
396 0 0       0 if(my $db_type = $col_info->{'RDBO_DB_TYPE'})
397             {
398 0         0 $self->db_type($db_type);
399             }
400              
401 0 0       0 if($col_info->{'REMARKS'})
402             {
403 0         0 $self->remarks($col_info->{'REMARKS'});
404             }
405              
406 0   0     0 $self->ordinal_position($col_info->{'ORDINAL_POSITION'} || 0);
407              
408 0         0 $self->default_value_sequence_name($col_info->{'rdbo_default_value_sequence_name'});
409              
410 0         0 return;
411             }
412              
413             sub perl_column_definition_attributes
414             {
415 0     0 0 0 my($self) = shift;
416              
417 0         0 my @attrs;
418              
419 0         0 ATTR: foreach my $attr ('type', sort keys %$self)
420             {
421 0 0       0 if($attr =~ /^(?: name(?:_sql)? | is_primary_key_member |
422             primary_key_position | method_name | method_code |
423             made_method_types | ordinal_position | select_sql |
424             undef_overrides_default | (?:builtin_)?triggers |
425             (?:builtin_)?trigger_index )$/x)
426             {
427 0         0 next ATTR;
428             }
429              
430 0 0       0 my $val = $self->can($attr) ? $self->$attr() : next ATTR;
431              
432 61     61   595 no warnings 'uninitialized';
  61         152  
  61         21351  
433 0 0 0     0 if(($attr eq 'check_in' || $attr eq 'values') &&
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
434             ref $val && ref $val eq 'ARRAY')
435             {
436 0 0       0 if($self->type eq 'set')
437             {
438 0         0 $val = perl_arrayref(array => $val, inline => 1);
439 0         0 $attr = 'values';
440             }
441             else
442             {
443 0         0 $val = perl_arrayref(array => $val, inline => 1);
444 0         0 $attr = 'check_in';
445             }
446             }
447             elsif($attr eq 'smart_modification' &&
448             (($self->smart_modification == ref($self)->new->smart_modification) ||
449             ($self->parent && $self->smart_modification == $self->parent->default_smart_modification)))
450             {
451 0         0 next ATTR;
452             }
453             elsif($attr eq 'undef_overrides_default' &&
454             (($self->undef_overrides_default == ref($self)->new->undef_overrides_default) ||
455             ($self->parent && $self->undef_overrides_default == $self->parent->column_undef_overrides_default)))
456             {
457 0         0 next ATTR;
458             }
459             elsif(!defined $val || ref $val || ($attr eq 'not_null' && !$self->not_null))
460             {
461 0         0 next ATTR;
462             }
463              
464 0 0 0     0 if($attr eq 'alias' && (!defined $val || $val eq $self->name))
      0        
465             {
466 0         0 next ATTR;
467             }
468              
469 0 0 0     0 if($attr eq 'overflow' && $val eq $self->init_overflow)
470             {
471 0         0 next ATTR;
472             }
473              
474             # Use shorter "sequence" hash key name for this attr
475 0 0       0 if($attr eq 'default_value_sequence_name')
476             {
477             # Only list an explicit sequence for serial columns if the sequence
478             # name differs from the default auto-generated sequence name.
479 0 0       0 if($self->type =~ /^(?:big)?serial$/)
480             {
481 0         0 my $seq = $self->default_value_sequence_name;
482              
483 0         0 my $meta = $self->parent;
484 0         0 my $db = $meta->db;
485              
486 0         0 my $auto_seq = $db->auto_sequence_name(table => $meta->table,
487             column => $self);
488              
489             # Use schema prefix on auto-generated name if necessary
490 0 0       0 if($seq =~ /^[^.]+\./)
491             {
492 0         0 my $schema = $meta->select_schema($db);
493 0 0       0 $auto_seq = "$schema.$auto_seq" if($schema);
494             }
495              
496 61     61   545 no warnings 'uninitialized';
  61         181  
  61         44396  
497 0 0       0 if(lc $seq ne lc $auto_seq)
498             {
499 0         0 push(@attrs, 'sequence');
500             }
501             }
502             else
503             {
504 0         0 push(@attrs, 'sequence');
505             }
506              
507 0         0 next;
508             }
509              
510 0 0       0 if($attr =~ /_method_name$/)
511             {
512 0         0 my $method = $self->$attr();
513              
514 0         0 my $skip = 1;
515              
516 0         0 foreach my $type ($self->auto_method_types)
517             {
518 0 0       0 $skip = 0 if($method ne $self->build_method_name_for_type($type));
519             }
520              
521 0 0       0 next ATTR if($skip);
522             }
523              
524 0         0 push(@attrs, $attr);
525             }
526              
527 0         0 return @attrs;
528             }
529              
530             sub perl_hash_definition
531             {
532 0     0 0 0 my($self, %args) = @_;
533              
534 0         0 my $meta = $self->parent;
535              
536 0         0 my $name_padding = $args{'name_padding'};
537              
538 0 0       0 my $indent = defined $args{'indent'} ? $args{'indent'} :
    0          
539             ($meta ? $meta->default_perl_indent : undef);
540              
541 0 0       0 my $inline = defined $args{'inline'} ? $args{'inline'} : 1;
542              
543 0         0 my %hash;
544              
545 0         0 foreach my $attr ($self->perl_column_definition_attributes)
546             {
547 0         0 $hash{$attr} = $self->$attr();
548             }
549              
550 0 0 0     0 if(defined $name_padding && $name_padding > 0)
551             {
552 0         0 return sprintf('%-*s => ', $name_padding, perl_quote_key($self->name)) .
553             perl_hashref(hash => \%hash,
554             inline => $inline,
555             indent => $indent,
556             sort_keys => \&_sort_keys);
557             }
558             else
559             {
560 0         0 return perl_quote_key($self->name) . ' => ' .
561             perl_hashref(hash => \%hash,
562             inline => $inline,
563             indent => $indent,
564             sort_keys => \&_sort_keys);
565             }
566             }
567              
568             sub _sort_keys
569             {
570 0 0   0   0 if($_[0] eq 'type')
    0          
571             {
572 0         0 return -1;
573             }
574             elsif($_[1] eq 'type')
575             {
576 0         0 return 1;
577             }
578              
579 0         0 return lc $_[0] cmp lc $_[1];
580             }
581              
582             sub lazy
583             {
584 264     264 1 491 my($self) = shift;
585              
586 264 100       1000 return $self->{'lazy'} unless(@_);
587              
588 2 50       6 if($_[0])
589             {
590 2 50       13 if($self->is_primary_key_member)
591             {
592 0         0 Carp::croak "The column '", $self->name, "' cannot be loaded on demand ",
593             "because it's part of the primary key";
594             }
595              
596 2         17 $self->{'lazy'} = 1;
597 2         10 $self->add_builtin_trigger(event => 'lazy_load',
598             name => 'load_on_demand',
599             code => $self->load_on_demand_on_get_code);
600              
601 2         12 $self->add_builtin_trigger(event => 'on_load',
602             name => 'load_on_demand',
603             code => $self->load_on_demand_on_set_code);
604              
605 2         13 $self->add_builtin_trigger(event => 'on_set',
606             name => 'load_on_demand',
607             code => $self->load_on_demand_on_set_code);
608             }
609             else
610             {
611 0         0 $self->{'lazy'} = 0;
612 0         0 $self->delete_builtin_trigger(event => 'on_get',
613             name => 'load_on_demand');
614              
615 0         0 $self->delete_builtin_trigger(event => 'on_load',
616             name => 'load_on_demand');
617              
618 0         0 $self->delete_builtin_trigger(event => 'on_set',
619             name => 'load_on_demand');
620             }
621              
622 2 50       8 if(my $meta = $self->parent)
623             {
624 2         8 $meta->refresh_lazy_column_tracking;
625             }
626              
627 2         24 return $self->{'lazy'};
628             }
629              
630             *is_lazy = \&lazy;
631             *load_on_demand = \&lazy;
632              
633 61     61   549 use constant LAZY_LOADED_KEY => lazy_column_values_loaded_key();
  61         191  
  61         505  
634              
635             sub load_on_demand_on_get_code
636             {
637 2     2 0 5 my($column) = shift;
638              
639 2         5 my($name, $mutator);
640              
641             return sub
642             {
643 0     0   0 my($self) = shift;
644              
645 0   0     0 $name ||= $column->name;
646 0 0 0     0 return if(!$self->{STATE_IN_DB()} || $self->{LAZY_LOADED_KEY()}{$name});
647              
648 0   0     0 $mutator ||= $column->mutator_method_name;
649 0         0 $self->$mutator($self->meta->get_column_value($self, $column));
650              
651 0         0 $self->{LAZY_LOADED_KEY()}{$name} = 1;
652 2         18 };
653             }
654              
655             sub load_on_demand_on_set_code
656             {
657 4     4 0 8 my($column) = shift;
658              
659 4         7 my $name;
660              
661             return sub
662             {
663 0     0   0 my($self) = shift;
664 0   0     0 $name ||= $column->name;
665 0         0 $self->{LAZY_LOADED_KEY()}{$name} = 1;
666 4         23 };
667             }
668              
669             our %Trigger_Events =
670             (
671             inflate => 1,
672             deflate => 1,
673             on_load => 1,
674             on_save => 1,
675             on_set => 1,
676             on_get => 1,
677             lazy_load => 1,
678             );
679              
680 54     54 0 228 sub trigger_events { keys %Trigger_Events }
681 3976     3976 0 9097 sub trigger_event_exists { exists $Trigger_Events{$_[1]} }
682              
683             sub builtin_triggers
684             {
685             # So evil...
686 2086     2086 0 7219 local $Triggers_Key = 'builtin_triggers';
687 2086         3828 shift->triggers(@_);
688             }
689              
690             sub triggers
691             {
692 3877     3877 1 8362 my($self, $event) = (shift, shift);
693              
694 3877 50       6721 Carp::croak "Invalid event: $event"
695             unless($self->trigger_event_exists($event));
696              
697 3877 50       7342 if(@_)
698             {
699 0 0       0 my $codes = (@_ > 1) ? [ @_ ] : $_[0];
700              
701 0 0       0 unless(ref $codes eq 'ARRAY')
702             {
703 0         0 Carp::croak "Expected code reference or a reference to an array ",
704             "of code references, but got: $codes";
705             }
706              
707 0         0 foreach my $code (@$codes)
708             {
709 0 0 0     0 unless((ref($code) || '') eq 'CODE')
710             {
711 0         0 Carp::croak "Not a code reference: $code";
712             }
713             }
714              
715 0 0       0 $self->{$Triggers_Key}{$event} = @$codes ? $codes : undef;
716 0         0 $self->reapply_triggers($event);
717 0         0 return;
718             }
719              
720 3877         10438 return $self->{$Triggers_Key}{$event};
721             }
722              
723             sub delete_builtin_triggers
724             {
725             # So evil...
726 1     1 0 11 local $Triggers_Key = 'builtin_triggers';
727 1         3 local $Trigger_Index_Key = 'builtin_trigger_index';
728 1         6 shift->delete_triggers(@_);
729             }
730              
731             sub delete_triggers
732             {
733 3     3 1 17 my($self, $event) = @_;
734              
735 3 100       13 my @events = $event ? $event : $self->trigger_events;
736              
737 3         7 foreach my $event (@events)
738             {
739 15 50       26 Carp::croak "Invalid event: $event"
740             unless($self->trigger_event_exists($event));
741              
742 15         60 $self->{$Triggers_Key}{$event} = undef;
743 15         34 $self->{$Trigger_Index_Key}{$event} = undef;
744             }
745              
746 3         10 return;
747             }
748              
749 0     0 1 0 sub disable_triggers { shift->triggers_disabled(1) }
750 0     0 1 0 sub enable_triggers { shift->triggers_disabled(0) }
751              
752             sub add_builtin_trigger
753             {
754 14     14 0 655 my($self, %args) = @_;
755              
756 14 100 66     47 if(@_ == 3 && $self->trigger_event_exists($_[1]))
757             {
758 4         9 my $event = $_[1];
759 4         6 my $code = $_[2];
760              
761 4         9 return $self->add_trigger(event => $event,
762             code => $code,
763             builtin => 1);
764             }
765              
766 10         37 return $self->add_trigger(%args, builtin => 1);
767             }
768              
769             sub add_trigger
770             {
771 49     49 1 1164 my($self, %args) = @_;
772              
773 49         81 my($event, $position, $code, $name);
774              
775 49 100 66     145 if(@_ == 3 && $self->trigger_event_exists($_[1]))
776             {
777 27         41 $event = $_[1];
778 27         38 $code = $_[2];
779             }
780             else
781             {
782 22         40 $event = $args{'event'};
783 22         36 $code = $args{'code'};
784             }
785              
786 49   66     151 $name = $args{'name'} || $self->generate_trigger_name;
787 49   100     143 $position = $args{'position'} || 'end';
788              
789 49   100     125 my $builtin = $args{'builtin'} || 0;
790 49 100       103 my $builtin_prefix = $builtin ? 'builtin_' : '';
791              
792 49 50       108 Carp::croak "Invalid event: '$event'"
793             unless($self->trigger_event_exists($event));
794              
795 49 50 50     148 unless((ref($code) || '') eq 'CODE')
796             {
797 0         0 Carp::croak "Not a code reference: $code";
798             }
799              
800 49 100       221 if($position =~ /^(?:end|last|push)$/)
    50          
801             {
802 47         75 push(@{$self->{$builtin_prefix . 'triggers'}{$event}}, $code);
  47         154  
803              
804 47 100       98 if($builtin)
805             {
806 13         34 $self->builtin_trigger_index($event, $name, $#{$self->{'builtin_triggers'}{$event}});
  13         66  
807             }
808             else
809             {
810 34         54 $self->trigger_index($event, $name, $#{$self->{'triggers'}{$event}});
  34         112  
811             }
812             }
813             elsif($position =~ /^(?:start|first|unshift)$/)
814             {
815 2         4 unshift(@{$self->{$builtin_prefix . 'triggers'}{$event}}, $code);
  2         8  
816              
817             # Shift all the other trigger positions
818 2 100       18 my $indexes = $builtin? $self->builtin_trigger_indexes($event) :
819             $self->trigger_indexes($event);
820              
821 2         9 foreach my $name (keys(%$indexes))
822             {
823 4         7 $indexes->{$name}++;
824             }
825              
826             # Set new position
827 2 100       6 if($builtin)
828             {
829 1         4 $self->builtin_trigger_index($event, $name, 0);
830             }
831             else
832             {
833 1         3 $self->trigger_index($event, $name, 0);
834             }
835             }
836 0         0 else { Carp::croak "Invalid trigger position: '$position'" }
837              
838 49         137 $self->reapply_triggers($event);
839 49         177 return;
840             }
841              
842             my $Trigger_Num = 0;
843              
844 39     39 0 167 sub generate_trigger_name { "dyntrig_${$}_" . ++$Trigger_Num }
845              
846 4 50   4 0 17 sub trigger_indexes { $_[0]->{'trigger_index'}{$_[1]} || {} }
847 10 100   10 0 1630 sub builtin_trigger_indexes { $_[0]->{'builtin_trigger_index'}{$_[1]} || {} }
848              
849             sub trigger_index
850             {
851 43     43 0 104 my($self, $event, $name) = (shift, shift, shift);
852              
853 43 100       137 if(@_)
854             {
855 35         156 return $self->{'trigger_index'}{$event}{$name} = shift;
856             }
857              
858 8         36 return $self->{'trigger_index'}{$event}{$name};
859             }
860              
861             sub builtin_trigger_index
862             {
863 22     22 0 59 my($self, $event, $name) = (shift, shift, shift);
864              
865 22 100       47 if(@_)
866             {
867 14         58 return $self->{'builtin_trigger_index'}{$event}{$name} = shift;
868             }
869              
870 8         34 return $self->{'builtin_trigger_index'}{$event}{$name};
871             }
872              
873 2     2 0 12 sub delete_builtin_trigger { shift->delete_trigger(@_, builtin => 1) }
874              
875             sub delete_trigger
876             {
877 4     4 1 19 my($self, %args) = @_;
878              
879 4 50       12 my $name = $args{'name'} or Carp::croak "Missing name parameter";
880 4         9 my $event = $args{'event'};
881 4   100     16 my $builtin = $args{'builtin'} || 0;
882              
883 4 100       11 my $builtin_text = $builtin ? ' builtin' : '';
884 4 100       10 my $builtin_prefix = $builtin ? 'builtin_' : '';
885              
886 4 50       10 Carp::croak "Invalid event: '$event'"
887             unless($self->trigger_event_exists($event));
888              
889 4 100       14 my $index = $builtin ? $self->builtin_trigger_index($event, $name) :
890             $self->trigger_index($event, $name);
891              
892 4 50       11 unless(defined $index)
893             {
894 0         0 Carp::croak "No$builtin_text trigger named '$name' for event '$event'";
895             }
896              
897 4         15 my $triggers = $self->{$builtin_prefix . 'triggers'}{$event};
898              
899             # Remove the trigger
900 4         9 splice(@$triggers, $index, 1);
901              
902 4 100       24 my $indexes = $builtin? $self->builtin_trigger_indexes($event) :
903             $self->trigger_indexes($event);
904              
905             # Remove its index
906 4         9 delete $indexes->{$name};
907              
908             # Shift all trigger indexes greater than $index
909 4         13 foreach my $name (keys(%$indexes))
910             {
911 6 100       17 $indexes->{$name}-- if($indexes->{$name} > $index);
912             }
913              
914 4         11 $self->reapply_triggers($event);
915             }
916              
917             sub apply_triggers
918             {
919 298     298 0 576 my($self, $event) = @_;
920              
921 298         421 my $method_types;
922              
923 298 100       578 if(defined $event)
924             {
925 53 50       151 $method_types = $self->event_method_type($event)
926             or Carp::croak "Invalid event: '$event'";
927              
928 53         1050 my %defined = map { $_ => 1 } $self->defined_method_types;
  0         0  
929              
930 53         99 $method_types = [ grep { $defined{$_} } @$method_types ];
  106         220  
931             }
932             else
933             {
934 245         543 $method_types = $self->defined_method_types;
935             }
936              
937 298         654 foreach my $method_type (@$method_types)
938             {
939 297         765 $self->apply_method_triggers($method_type);
940             }
941              
942 298         1010 return;
943             }
944              
945 53     53 0 119 sub reapply_triggers { shift->apply_triggers(@_) }
946              
947             sub apply_method_triggers
948             {
949 297     297 0 560 my($self, $type) = @_;
950              
951 297         466 my $column = $self; # $self masked in a deeper context below
952              
953 297         874 my $class = $self->parent->class;
954              
955 297 50       788 my $method_name = $self->method_name($type) or
956             Carp::confess "No method name for method type '$type'";
957              
958 297         688 my $method_code = $self->method_code($type);
959              
960             # Save the original method code
961 297 50       661 unless($method_code)
962             {
963 297         1188 $method_code = $class->can($method_name);
964 297         648 $self->method_code($type, $method_code);
965             }
966              
967             # Copying out into scalars to avoid method calls in the sub itself
968 297   50     694 my $inflate_code = $self->triggers('inflate') || 0;
969 297   50     703 my $deflate_code = $self->triggers('deflate') || 0;
970 297   50     582 my $on_load_code = $self->triggers('on_load') || 0;
971 297   50     637 my $on_save_code = $self->triggers('on_save') || 0;
972 297   50     579 my $on_set_code = $self->triggers('on_set') || 0;
973 297   50     595 my $on_get_code = $self->triggers('on_get') || 0;
974              
975 297         475 my $builtins;
976              
977             # Add built-ins, if any
978 297 50 0     608 unshift(@{$inflate_code ||= []}, @$builtins)
  0         0  
979             if($builtins = $self->builtin_triggers('inflate'));
980              
981 297 50 0     564 unshift(@{$deflate_code ||= []}, @$builtins)
  0         0  
982             if($builtins = $self->builtin_triggers('deflate'));
983              
984 297 50 0     595 unshift(@{$on_load_code ||= []}, @$builtins)
  0         0  
985             if($builtins = $self->builtin_triggers('on_load'));
986              
987 297 50 0     619 unshift(@{$on_save_code ||= []}, @$builtins)
  0         0  
988             if($builtins = $self->builtin_triggers('on_save'));
989              
990 297 50 0     567 unshift(@{$on_set_code ||= []}, @$builtins)
  0         0  
991             if($builtins = $self->builtin_triggers('on_set'));
992              
993 297 50 0     518 unshift(@{$on_get_code ||= []}, @$builtins)
  0         0  
994             if($builtins = $self->builtin_triggers('on_get'));
995              
996 297         537 my $lazy_load_code = $self->builtin_triggers('lazy_load');
997              
998 297         703 my $key = $self->hash_key;
999 297         1022 my $formatted_key = column_value_formatted_key($key);
1000 297         795 my $is_inflated_key = column_value_is_inflated_key($key);
1001              
1002 297         864 my $uses_formatted_key = $self->method_uses_formatted_key($type);
1003              
1004 297 100       977 if($type eq 'get_set')
    50          
    50          
1005             {
1006 193 50 33     1643 if($inflate_code || $deflate_code ||
      33        
      33        
      33        
      33        
      33        
1007             $on_load_code || $on_save_code ||
1008             $on_set_code || $on_get_code ||
1009             $lazy_load_code)
1010             {
1011             my $method = sub
1012             {
1013 0     0   0 my($self) = $_[0];
1014              
1015 0 0       0 if($column->method_should_set('get_set', \@_))
1016             {
1017             # This is a duplication of the 'set' code below. Yes, it's
1018             # duplicated to save one measly function call. So sue me.
1019 0 0       0 if($self->{STATE_LOADING()})
1020             {
1021 0 0       0 $self->{$is_inflated_key} = 0 unless($uses_formatted_key);
1022              
1023 0         0 my @ret;
1024              
1025 0 0       0 if(wantarray)
1026             {
1027 0         0 @ret = &$method_code; # magic call using current @_
1028             }
1029             else
1030             {
1031 0         0 $ret[0] = &$method_code; # magic call using current @_
1032             }
1033              
1034 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1035             {
1036 0         0 local $self->{'triggers_disabled'} = 1;
1037              
1038 0 0       0 if($on_load_code)
1039             {
1040 0         0 foreach my $code (@$on_load_code)
1041             {
1042 0         0 $code->($self);
1043             }
1044             }
1045             }
1046              
1047 0 0       0 return wantarray ? @ret : $ret[0];
1048             }
1049             else
1050             {
1051 0 0       0 $self->{$is_inflated_key} = 0 unless($uses_formatted_key);
1052              
1053 0         0 my @ret;
1054              
1055 0 0       0 if(wantarray)
1056             {
1057 0         0 @ret = &$method_code; # magic call using current @_
1058             }
1059             else
1060             {
1061 0         0 $ret[0] = &$method_code; # magic call using current @_
1062             }
1063              
1064 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1065             {
1066 0         0 local $self->{'triggers_disabled'} = 1;
1067              
1068 0 0       0 if($on_set_code)
1069             {
1070 0         0 foreach my $code (@$on_set_code)
1071             {
1072 0         0 $code->($self);
1073             }
1074             }
1075             }
1076              
1077 0 0       0 return wantarray ? @ret : $ret[0];
1078             }
1079             }
1080             else # getting
1081             {
1082             # This is a duplication of the 'get' code below. Yes, it's
1083             # duplicated to save one measly function call. So sue me.
1084 0 0       0 if($self->{STATE_SAVING()})
1085             {
1086 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1087             {
1088 0         0 local $self->{'triggers_disabled'} = 1;
1089              
1090 0 0       0 if($deflate_code)
1091             {
1092 0 0       0 if($uses_formatted_key)
1093             {
1094 0 0       0 my $db = $self->db or die "Missing Rose::DB object attribute";
1095 0   0     0 my $driver = $db->driver || 'unknown';
1096              
1097 0 0       0 unless(defined $self->{$formatted_key,$driver})
1098             {
1099 0         0 my $value = $self->{$key};
1100              
1101             # Call method to get default value
1102 0 0       0 $value = $method_code->($self) unless(defined $value);
1103              
1104 0         0 foreach my $code (@$deflate_code)
1105             {
1106 0         0 $value = $code->($self, $value);
1107             }
1108              
1109 0         0 $self->{$formatted_key,$driver} = $value;
1110             }
1111             }
1112             else
1113             {
1114 0         0 my $value = $self->{$key};
1115              
1116             # Call method to get default value
1117 0 0       0 $value = $method_code->($self) unless(defined $value);
1118              
1119 0         0 foreach my $code (@$deflate_code)
1120             {
1121 0         0 $value = $code->($self, $value);
1122             }
1123              
1124 0         0 $self->{$key} = $value;
1125 0         0 $self->{$is_inflated_key} = 0;
1126             }
1127             }
1128              
1129 0 0 0     0 if($on_save_code && !$self->{SAVING_FOR_LOAD()})
1130             {
1131 0         0 foreach my $code (@$on_save_code)
1132             {
1133 0         0 $code->($self);
1134             }
1135             }
1136             }
1137              
1138 0         0 &$method_code; # magic call using current @_
1139             }
1140             else
1141             {
1142 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1143             {
1144 0         0 local $self->{'triggers_disabled'} = 1;
1145              
1146 0 0       0 if($lazy_load_code)
1147             {
1148 0         0 foreach my $code (@$lazy_load_code)
1149             {
1150 0         0 $code->($self);
1151             }
1152             }
1153              
1154 0 0       0 if($inflate_code)
1155             {
1156 0         0 my $value;
1157             my $key_was_defined;
1158              
1159 0 0       0 if(defined $self->{$key})
1160             {
1161 0         0 $value = $self->{$key};
1162 0         0 $key_was_defined = 1;
1163             }
1164             else
1165             {
1166 0         0 $key_was_defined = 0;
1167             # Invoke built-in default and inflation code
1168             # (The call must not be in void context)
1169 0         0 $value = $method_code->($self, @_[1 .. $#_]);
1170             }
1171              
1172 0 0 0     0 unless($self->{$is_inflated_key} && $key_was_defined)
1173             {
1174 0 0       0 if($uses_formatted_key)
1175             {
1176 0         0 foreach my $code (@$inflate_code)
1177             {
1178 0         0 $value = $code->($self, $value);
1179             }
1180              
1181 0 0       0 my $db = $self->db or die "Missing Rose::DB object attribute";
1182 0   0     0 my $driver = $db->driver || 'unknown';
1183              
1184             # Invalidate deflated value
1185 0         0 $self->{$formatted_key,$driver} = undef;
1186              
1187             # Set new inflated value
1188 0         0 $self->{$key} = $value;
1189             }
1190             else
1191             {
1192 0         0 foreach my $code (@$inflate_code)
1193             {
1194 0         0 $value = $code->($self, $value);
1195             }
1196              
1197 0         0 $self->{$is_inflated_key} = 1;
1198 0         0 $self->{$key} = $value;
1199             }
1200              
1201 0         0 $self->{$is_inflated_key} = 1;
1202             }
1203             }
1204              
1205 0 0       0 if($on_get_code)
1206             {
1207 0         0 foreach my $code (@$on_get_code)
1208             {
1209 0         0 $code->($self);
1210             }
1211             }
1212             }
1213              
1214 0         0 &$method_code; # magic call using current @_
1215             }
1216             }
1217 0         0 };
1218              
1219 61     61   701 no warnings;
  61         225  
  61         3066  
1220 61     61   480 no strict 'refs';
  61         164  
  61         3722  
1221 0         0 *{"${class}::$method_name"} = $method;
  0         0  
1222             }
1223             else # no applicable triggers for 'get'
1224             {
1225 61     61   431 no warnings;
  61         226  
  61         2643  
1226 61     61   437 no strict 'refs';
  61         219  
  61         45482  
1227 193         317 *{"${class}::$method_name"} = $method_code;
  193         963  
1228             }
1229             }
1230             elsif($type eq 'get')
1231             {
1232 0 0 0     0 if($inflate_code || $deflate_code || $on_save_code || $on_get_code || $lazy_load_code)
      0        
      0        
      0        
1233             {
1234             my $method = sub
1235             {
1236 0     0   0 my($self) = $_[0];
1237              
1238 0 0       0 if($self->{STATE_SAVING()})
1239             {
1240 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1241             {
1242 0         0 local $self->{'triggers_disabled'} = 1;
1243              
1244 0 0       0 if($deflate_code)
1245             {
1246 0 0       0 if($uses_formatted_key)
1247             {
1248 0 0       0 my $db = $self->db or die "Missing Rose::DB object attribute";
1249 0   0     0 my $driver = $db->driver || 'unknown';
1250              
1251 0 0       0 unless(defined $self->{$formatted_key,$driver})
1252             {
1253 0         0 my $value = $self->{$key};
1254              
1255             # Call method to get default value
1256 0 0       0 $value = $method_code->($self) unless(defined $value);
1257              
1258 0         0 foreach my $code (@$deflate_code)
1259             {
1260 0         0 $value = $code->($self, $value);
1261             }
1262              
1263 0         0 $self->{$formatted_key,$driver} = $value;
1264             }
1265             }
1266             else
1267             {
1268 0         0 my $value = $self->{$key};
1269              
1270             # Call method to get default value
1271 0 0       0 $value = $method_code->($self) unless(defined $value);
1272              
1273 0         0 foreach my $code (@$deflate_code)
1274             {
1275 0         0 $value = $code->($self, $value);
1276             }
1277              
1278 0         0 $self->{$key} = $value;
1279 0         0 $self->{$is_inflated_key} = 0;
1280             }
1281             }
1282              
1283 0 0 0     0 if($on_save_code && !$self->{SAVING_FOR_LOAD()})
1284             {
1285 0         0 foreach my $code (@$on_save_code)
1286             {
1287 0         0 $code->($self);
1288             }
1289             }
1290             }
1291              
1292 0         0 &$method_code; # magic call using current @_
1293             }
1294             else
1295             {
1296 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1297             {
1298 0         0 local $self->{'triggers_disabled'} = 1;
1299              
1300 0 0       0 if($lazy_load_code)
1301             {
1302 0         0 foreach my $code (@$lazy_load_code)
1303             {
1304 0         0 $code->($self);
1305             }
1306             }
1307              
1308 0 0       0 if($inflate_code)
1309             {
1310 0         0 my $value;
1311             my $key_was_defined;
1312              
1313 0 0       0 if(defined $self->{$key})
1314             {
1315 0         0 $value = $self->{$key};
1316 0         0 $key_was_defined = 1;
1317             }
1318             else
1319             {
1320 0         0 $key_was_defined = 0;
1321             # Invoke built-in default and inflation code
1322             # (The call must not be in void context)
1323 0         0 $value = $method_code->($self, @_[1 .. $#_]);
1324             }
1325              
1326 0 0 0     0 unless($self->{$is_inflated_key} && $key_was_defined)
1327             {
1328 0 0       0 if($uses_formatted_key)
1329             {
1330 0         0 foreach my $code (@$inflate_code)
1331             {
1332 0         0 $value = $code->($self, $value);
1333             }
1334              
1335 0 0       0 my $db = $self->db or die "Missing Rose::DB object attribute";
1336 0   0     0 my $driver = $db->driver || 'unknown';
1337              
1338             # Invalidate deflated value
1339 0         0 $self->{$formatted_key,$driver} = undef;
1340              
1341             # Set new inflated value
1342 0         0 $self->{$key} = $value;
1343             }
1344             else
1345             {
1346 0         0 foreach my $code (@$inflate_code)
1347             {
1348 0         0 $value = $code->($self, $value);
1349             }
1350              
1351 0         0 $self->{$is_inflated_key} = 1;
1352 0         0 $self->{$key} = $value;
1353             }
1354              
1355 0         0 $self->{$is_inflated_key} = 1;
1356             }
1357             }
1358              
1359 0 0       0 if($on_get_code)
1360             {
1361 0         0 foreach my $code (@$on_get_code)
1362             {
1363 0         0 $code->($self);
1364             }
1365             }
1366             }
1367              
1368 0         0 &$method_code; # magic call using current @_
1369             }
1370 0         0 };
1371              
1372 61     61   572 no warnings;
  61         167  
  61         2789  
1373 61     61   428 no strict 'refs';
  61         167  
  61         3205  
1374 0         0 *{"${class}::$method_name"} = $method;
  0         0  
1375             }
1376             else # no applicable triggers for 'get'
1377             {
1378 61     61   425 no warnings;
  61         157  
  61         2546  
1379 61     61   414 no strict 'refs';
  61         157  
  61         20795  
1380 0         0 *{"${class}::$method_name"} = $method_code;
  0         0  
1381             }
1382             }
1383             elsif($type eq 'set')
1384             {
1385 0 0 0     0 if($on_load_code || $on_set_code)
1386             {
1387             my $method = sub
1388             {
1389 0     0   0 my($self) = $_[0];
1390              
1391 0 0       0 if($self->{STATE_LOADING()})
1392             {
1393 0 0       0 $self->{$is_inflated_key} = 0 unless($uses_formatted_key);
1394              
1395 0         0 my @ret;
1396              
1397 0 0       0 if(wantarray)
1398             {
1399 0         0 @ret = &$method_code; # magic call using current @_
1400             }
1401             else
1402             {
1403 0         0 $ret[0] = &$method_code; # magic call using current @_
1404             }
1405              
1406 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1407             {
1408 0         0 local $self->{'triggers_disabled'} = 1;
1409              
1410 0 0       0 if($on_load_code)
1411             {
1412 0         0 foreach my $code (@$on_load_code)
1413             {
1414 0         0 $code->($self);
1415             }
1416             }
1417             }
1418              
1419 0 0       0 return wantarray ? @ret : $ret[0];
1420             }
1421             else
1422             {
1423 0 0       0 $self->{$is_inflated_key} = 0 unless($uses_formatted_key);
1424              
1425 0         0 my @ret;
1426              
1427 0 0       0 if(wantarray)
1428             {
1429 0         0 @ret = &$method_code; # magic call using current @_
1430             }
1431             else
1432             {
1433 0         0 $ret[0] = &$method_code; # magic call using current @_
1434             }
1435              
1436 0 0 0     0 unless($column->{'triggers_disabled'} || $self->{'triggers_disabled'})
1437             {
1438 0         0 local $self->{'triggers_disabled'} = 1;
1439              
1440 0 0       0 if($on_set_code)
1441             {
1442 0         0 foreach my $code (@$on_set_code)
1443             {
1444 0         0 $code->($self);
1445             }
1446             }
1447             }
1448              
1449 0 0       0 return wantarray ? @ret : $ret[0];
1450             }
1451 0         0 };
1452              
1453 61     61   542 no warnings;
  61         181  
  61         2584  
1454 61     61   484 no strict 'refs';
  61         185  
  61         3253  
1455 0         0 *{"${class}::$method_name"} = $method;
  0         0  
1456             }
1457             else # no applicable triggers for 'set'
1458             {
1459 61     61   436 no warnings;
  61         161  
  61         2787  
1460 61     61   461 no strict 'refs';
  61         174  
  61         13987  
1461 0         0 *{"${class}::$method_name"} = $method_code;
  0         0  
1462             }
1463             }
1464             }
1465              
1466             sub method_code
1467             {
1468 891     891 0 1714 my($self, $type) = (shift, shift);
1469              
1470 891 50       1789 Carp::confess "Missing or undefined type argument" unless(defined $type);
1471              
1472 891 100       1705 if(@_)
1473             {
1474 594         1826 Scalar::Util::weaken($self->{'method_code'}{$type} = shift);
1475             }
1476              
1477 891         2043 return $self->{'method_code'}{$type};
1478             }
1479              
1480             sub make_methods
1481             {
1482 245     245 1 469 my($self) = shift;
1483              
1484 245         876 $self->SUPER::make_methods(@_);
1485              
1486             # Check if we can fold all method type name attributes
1487             # into an alias attribute. We can do this if the accessor,
1488             # mutator, and rw method names are all the same and are not
1489             # the same as the column name.
1490 61     61   553 no warnings 'uninitialized';
  61         181  
  61         10029  
1491 245 100 33     633 if(($self->accessor_method_name eq $self->mutator_method_name &&
      66        
1492             $self->mutator_method_name eq $self->rw_method_name &&
1493             $self->rw_method_name ne $self->name))
1494             {
1495 55         148 $self->alias($self->rw_method_name);
1496             }
1497              
1498 245         671 $self->apply_triggers;
1499             }
1500              
1501 0     0 0   sub dbi_requires_bind_param { 0 }
1502              
1503             # It's important to return undef or a hashref, not an empty list
1504 0     0 0   sub dbi_bind_param_attrs { undef }
1505              
1506             1;
1507              
1508             __END__
1509              
1510             =head1 NAME
1511              
1512             Rose::DB::Object::Metadata::Column - Base class for database column metadata objects.
1513              
1514             =head1 SYNOPSIS
1515              
1516             package MyColumnType;
1517              
1518             use Rose::DB::Object::Metadata::Column;
1519             our @ISA = qw(Rose::DB::Object::Metadata::Column);
1520             ...
1521              
1522             =head1 DESCRIPTION
1523              
1524             This is the base class for objects that store and manipulate database column metadata. Column metadata objects store information about columns (data type, size, etc.) and are responsible for parsing, formatting, and creating object methods that manipulate column values.
1525              
1526             L<Rose::DB::Object::Metadata::Column> objects stringify to the value returned by the L<name|/name> method. This allows full-blown column objects to be used in place of column name strings in most situations.
1527              
1528             =head2 MAKING METHODS
1529              
1530             A L<Rose::DB::Object::Metadata::Column>-derived object is responsible for creating object methods that manipulate column values. Each column object can make zero or more methods for each available column method type. A column method type describes the purpose of a method. The default column method types are:
1531              
1532             =over 4
1533              
1534             =item C<get_set>
1535              
1536             A method that can both get and set the column value. If an argument is passed, then the column value is set. In either case, the current column value is returned.
1537              
1538             =item C<get>
1539              
1540             A method that returns the current column value.
1541              
1542             =item C<set>
1543              
1544             A method that sets the column value.
1545              
1546             =back
1547              
1548             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.
1549              
1550             These methods make up the "public" interface to column 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.
1551              
1552             A L<Rose::DB::Object::Metadata::Column> 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.
1553              
1554             Using this system, four pieces of information are needed to create a method on behalf of a L<Rose::DB::Object::Metadata::Column>-derived object:
1555              
1556             =over 4
1557              
1558             =item * The B<column method type> (e.g., C<get_set>, C<get>, C<set>)
1559              
1560             =item * The B<method maker class> (e.g., L<Rose::DB::Object::MakeMethods::Generic>)
1561              
1562             =item * The B<method maker method type> (e.g., L<scalar|Rose::DB::Object::MakeMethods::Generic/scalar>)
1563              
1564             =item * The B<method maker arguments> (e.g., C<interface =E<gt> 'get_set_init'>)
1565              
1566             =back
1567              
1568             This information can be organized conceptually into a "method map" that connects a column method type to a method maker class and, finally, to one particular method type within that class, and its arguments.
1569              
1570             The default method map is:
1571              
1572             =over 4
1573              
1574             =item C<get_set>
1575              
1576             L<Rose::DB::Object::MakeMethods::Generic>, L<scalar|Rose::DB::Object::MakeMethods::Generic/scalar>, C<interface =E<gt> 'get_set', ...>
1577              
1578             =item C<get>
1579              
1580             L<Rose::DB::Object::MakeMethods::Generic>, L<scalar|Rose::DB::Object::MakeMethods::Generic/scalar>, C<interface =E<gt> 'get', ...>
1581              
1582             =item C<set>
1583              
1584             L<Rose::DB::Object::MakeMethods::Generic>, L<scalar|Rose::DB::Object::MakeMethods::Generic/scalar>, C<interface =E<gt> 'set', ...>
1585              
1586             =back
1587              
1588             Each item in the map is a column method type. For each column method type, the method maker class, the method maker method type, and the "interesting" method maker arguments are listed, in that order.
1589              
1590             The "..." in the method maker arguments is meant to indicate that other arguments have been omitted. For example, the column object's L<default|/default> value is passed as part of the arguments for all method types. These arguments that are common to all column method types are routinely omitted from the method map for the sake of brevity. If there are no "interesting" method maker arguments, then "..." may appear by itself.
1591              
1592             The purpose of documenting the method map is to answer the question, "What kind of method(s) will be created by this column 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.
1593              
1594             To this end, each L<Rose::DB::Object::Metadata::Column>-derived class in the L<Rose::DB::Object> module distribution will list its method map in its documentation. This is a concise way to document the behavior that is specific to each column class, while omitting the common functionality (which is documented here, in the column base class).
1595              
1596             Remember, the existence and behavior of the method map is really implementation detail. A column object is free to implement the public method-making interface however it wants, without regard to any conceptual or actual method map. It must then, of course, document what kinds of methods it makes for each of its method types, but it does not have to use a method map to do so.
1597              
1598             =head2 TRIGGERS
1599              
1600             Triggers allow code to run in response to certain column-related events. An event may trigger zero or more pieces of code. The names and behaviors of the various kinds of events are as follows.
1601              
1602             =over 4
1603              
1604             =item B<on_get>
1605              
1606             Triggered when a column value is retrieved for some purpose I<other than> storage in the database. For example, when end-user code retrieves a column value by calling an accessor method, this event is triggered. This event is I<not> triggered when a column value is retrieved while the object is being L<save|Rose::DB::Object/save>d into the database.
1607              
1608             Each piece of code responding to an C<on_get> event will be passed a single argument: a reference to the object itself. The return value is not used.
1609              
1610             =item B<on_set>
1611              
1612             Triggered when a column value is set to a value that came from somewhere I<other than> the database. For example, when end-user code sets a column value by calling a mutator method, this event is triggered. This event is I<not> triggered when a column value is set while the object is being L<load|Rose::DB::Object/load>ed from the database.
1613              
1614             The C<on_set> event occurs I<after> the column value has been set. Each piece of code responding to an C<on_set> event will be passed a single argument: a reference to the object itself. The return value is not used.
1615              
1616             =item B<on_load>
1617              
1618             Triggered when a column value is set while an object is being L<load|Rose::DB::Object/load>ed from the database.
1619              
1620             The C<on_load> event occurs I<after> the column value has been loaded. Each piece of code responding to an C<on_load> event will be passed a single argument: a reference to the object itself. The return value is not used.
1621              
1622             =item B<on_save>
1623              
1624             Triggered when a column value is retrieved while an object is being L<save|Rose::DB::Object/save>d into the database.
1625              
1626             Each piece of code responding to an C<on_save> event will be passed a single argument: a reference to the object itself. The return value is not used.
1627              
1628             =item B<inflate>
1629              
1630             Triggered when a column value is retrieved for some purpose I<other than> storage in the database. For example, when end-user code retrieves a column value by calling an accessor method, and that value came directly from the database, this event is triggered.
1631              
1632             Inflation will only happen "as needed." That is, a value that has already been inflated will not be inflated again, and a value that comes from the database and goes back into it without ever being retrieved by end-user code will never be inflated at all.
1633              
1634             Each piece of code responding to an C<inflate> event will be passed two arguments: a reference to the object itself and the value to be inflated. It should return an inflated version of that value. Note that the value to be inflated may have come from the database, or from end-user code. Be prepared to handle almost anything.
1635              
1636             =item B<deflate>
1637              
1638             Triggered when a column value that did not come directly from the database needs to be put into the database. For example, when a column value set by end-user code needs to be saved into the database, this event is triggered.
1639              
1640             Deflation will only happen "as needed." That is, a value that has already been deflated will not be deflated again, and a value that comes from the database and goes back into it without ever being retrieved by end-user code will never need to be deflated at all.
1641              
1642             Each piece of code responding to a C<deflate> event will be passed two arguments: a reference to the object itself and the value to be deflated. It should return a deflated version of that value suitable for saving into the currently connected database. Note that the value to be deflated may have come from the database, or from end-user code. Be prepared to handle almost anything.
1643              
1644             =back
1645              
1646             All triggers are L<disabled|/disable_triggers> while inside code called in response to a trigger event. Such code may call any other column methods, including methods that belong to its own column, without fear of infinite recursion into trigger service subroutines. Alternately, triggers may be explicitly L<enabled|/enable_triggers> if desired. Just watch out for infinite loops.
1647              
1648             For performance reasons, none of the column classes bundled with L<Rose::DB::Object> use triggers by default. Some of them do inflate and deflate values, but they do so internally (inside the accessor and mutator methods created by the L<Rose::Object::MakeMethods>-derived classes that service those column types). You can still add triggers to these column types, but the interaction between the internal inflate/deflate actions and the triggers for those same events can become a bit "non-obvious."
1649              
1650             =head1 CLASS METHODS
1651              
1652             =over 4
1653              
1654             =item B<default_auto_method_types [TYPES]>
1655              
1656             Get or set the default list of L<auto_method_types|/auto_method_types>. TYPES should be a list of column method types. Returns the list of default column method types (in list context) or a reference to an array of the default column method types (in scalar context). The default list contains only the "get_set" column method type.
1657              
1658             =item B<default_undef_overrides_default [BOOL]>
1659              
1660             Get or set the default value of the L<undef_overrides_default|/undef_overrides_default> attribute. The default value is undef.
1661              
1662             This default only applies when the column does not have a parent metadata object or if the metadata object's L<column_undef_overrides_default|Rose::DB::Object::Metadata/column_undef_overrides_default> method returns undef.
1663              
1664             =back
1665              
1666             =head1 CONSTRUCTOR
1667              
1668             =over 4
1669              
1670             =item B<new PARAMS>
1671              
1672             Constructs a new object based on PARAMS, where PARAMS are
1673             name/value pairs. Any object method is a valid parameter name.
1674              
1675             =back
1676              
1677             =head1 OBJECT METHODS
1678              
1679             =over 4
1680              
1681             =item B<accessor_method_name>
1682              
1683             Returns the name of the method used to get the column value. This is a convenient shortcut for:
1684              
1685             $column->method_name('get') || $column->method_name('get_set');
1686              
1687             =item B<add_trigger [ EVENT, CODEREF | PARAMS ]>
1688              
1689             Add a trigger, as specified by either an event and a code reference, or a set of named parameters that include an event, a code reference, and an optional name and position for the trigger.
1690              
1691             If there are only two arguments, and the first is a valid event name, then the second must be a code reference. Otherwise, the arguments are taken as named parameters.
1692              
1693             Valid parameters are:
1694              
1695             =over 4
1696              
1697             =item C<code CODEREF>
1698              
1699             A reference to a subroutine that will be called in response to a trigger event. This parameter is required. See the L<triggers|/TRIGGERS> section of this documentation for a description of the arguments to and return values expected from these routines for each type of event.
1700              
1701             =item C<event EVENT>
1702              
1703             The name of the event that activates this trigger. This parameter is required. Valid event names are C<on_get>, C<on_set>, C<on_load>, C<on_save>, C<inflate>, and C<deflate>. See the L<triggers|/TRIGGERS> section of this documentation for more information on these event types.
1704              
1705             =item C<name NAME>
1706              
1707             An optional name mapped to the triggered subroutine. If a name is not supplied, one will be generated. A known name is necessary if you ever want to L<delete|/delete_trigger> a particular subroutine from the list of triggered subroutine for a given event.
1708              
1709             =item C<position POS>
1710              
1711             The position in the list of triggered subroutines to add this new code. Triggered subroutines are kept in an ordered list. By default, new triggers are added to the end of the list, which means they run last. Valid position arguments are:
1712              
1713             =over
1714              
1715             =item C<end>, C<last>, or C<push>
1716              
1717             Add to the end of the list.
1718              
1719             =item C<start>, C<first>, or C<unshift>
1720              
1721             Add to the beginning of the list.
1722              
1723             =back
1724              
1725             If omitted, the position defaults to "end."
1726              
1727             =back
1728              
1729             Examples:
1730              
1731             # Add trigger using an event name and a code reference
1732             $column->add_trigger(on_set => sub { print "set!\n" });
1733              
1734             # Same as above, but using named parameters
1735             $column->add_trigger(event => 'on_set',
1736             code => sub { print "set!\n" });
1737              
1738             # Same as the above, but with a custom name and explicit position
1739             $column->add_trigger(event => 'on_set',
1740             code => sub { print "set!\n" },
1741             name => 'debugging',
1742             position => 'end');
1743              
1744             =item B<alias [NAME]>
1745              
1746             Get or set an alternate L<name|/name> for this column.
1747              
1748             =item B<available_method_types>
1749              
1750             Returns the full list of column method types supported by this class.
1751              
1752             =item B<auto_method_types [TYPES]>
1753              
1754             Get or set the list of column method types that are automatically created when L<make_methods|/make_methods> is called without an explicit list of column method types. The default list is determined by the L<default_auto_method_types|/default_auto_method_types> class method.
1755              
1756             =item B<build_method_name_for_type TYPE>
1757              
1758             Return a method name for the column method type TYPE. The default implementation returns the column's L<alias|/alias> (if defined) or L<name|/name> for the method type "get_set", and the same thing with a "get_" or "set_" prefix for the "get" and "set" column method types, respectively.
1759              
1760             =item B<default [VALUE]>
1761              
1762             Get or set the default value of the column.
1763              
1764             =item B<default_exists>
1765              
1766             Returns true if a default value exists for this column (even if it is undef), false otherwise.
1767              
1768             =item B<delete_default>
1769              
1770             Deletes the default value for this column.
1771              
1772             =item B<delete_trigger PARAMS>
1773              
1774             Delete a triggered subroutine from the list of triggered subroutines for a given event. You must know the name applied to the triggered subroutine when it was L<added|/add_trigger> in order to delete it. PARAMS are name/value pairs.
1775              
1776             =over 4
1777              
1778             =item C<name NAME>
1779              
1780             The name applied to the triggered subroutine when it was added via the L<added|/add_trigger> method. This parameter is required.
1781              
1782             =item C<event EVENT>
1783              
1784             The name of the event that activates this trigger. This parameter is required. Valid event names are C<on_get>, C<on_set>, C<on_load>, C<on_save>, C<inflate>, and C<deflate>. See the L<triggers|/TRIGGERS> section of this documentation for more information on these event types.
1785              
1786             =back
1787              
1788             A fatal error will occur if a matching trigger cannot be found.
1789              
1790             Examples:
1791              
1792             # Add two named triggers
1793             $column->add_trigger(event => 'on_set',
1794             code => sub { print "set!\n" },
1795             name => 'debugging');
1796              
1797             $column->add_trigger(event => 'on_set',
1798             code => sub { shift->do_something() },
1799             name => 'side_effect');
1800              
1801             # Delete the side_effect trigger
1802             $column->delete_trigger(event => 'on_set',
1803             name => 'side_effect');
1804              
1805             # Fatal error: no trigger subroutine for this column
1806             # named "nonesuch" for the event type "on_set"
1807             $column->delete_trigger(event => 'on_set',
1808             name => 'nonesuch');
1809              
1810             =item B<delete_triggers [EVENT]>
1811              
1812             Delete all triggers for EVENT. If EVENT is omitted, delete all triggers for all events for this column.
1813              
1814             Valid event names are C<on_get>, C<on_set>, C<on_load>, C<on_save>, C<inflate>, and C<deflate>. See the L<triggers|/TRIGGERS> section of this documentation for more information on these event types.
1815              
1816             =item B<disable_triggers>
1817              
1818             Disable all triggers for this column.
1819              
1820             =item B<enable_triggers>
1821              
1822             Enable all triggers for this column.
1823              
1824             =item B<format_value DB, VALUE>
1825              
1826             Convert VALUE into a string suitable for the database column of this type. VALUE is expected to be like the return value of the L<parse_value|/parse_value> method. DB is a L<Rose::DB> object that may be used as part of the parsing process. Both arguments are required.
1827              
1828             =item B<is_primary_key_member [BOOL]>
1829              
1830             Get or set the boolean flag that indicates whether or not this column is part of the primary key for its table.
1831              
1832             =item B<load_on_demand [BOOL]>
1833              
1834             Get or set a boolean value that indicates whether or not a column's value should be loaded only when needed. If true, then the column's value will not automatically be fetched from the database when an object is L<loaded|Rose::DB::Object/load>. It will be fetched only if the column value is subsequently requested through its L<accessor method|/accessor_method_name>. (This is often referred to as "lazy loading.") The default value is false.
1835              
1836             Note: a column that is part of a primary key cannot be loaded on demand.
1837              
1838             =item B<lazy [BOOL]>
1839              
1840             This is an alias for the L<load_on_demand|/load_on_demand> method. It exists to allow this common usage scenario:
1841              
1842             __PACKAGE__->meta->columns
1843             (
1844             ...
1845             notes => { type => 'text', length => 1024, lazy => 1 },
1846             );
1847              
1848             without requiring the longer C<load_on_demand> parameter name to be used.
1849              
1850             =item B<make_methods PARAMS>
1851              
1852             Create object method used to manipulate column values. PARAMS are name/value pairs. Valid PARAMS are:
1853              
1854             =over 4
1855              
1856             =item C<preserve_existing BOOL>
1857              
1858             Boolean flag that indicates whether or not to preserve existing methods in the case of a name conflict.
1859              
1860             =item C<replace_existing BOOL>
1861              
1862             Boolean flag that indicates whether or not to replace existing methods in the case of a name conflict.
1863              
1864             =item C<target_class CLASS>
1865              
1866             The class in which to make the method(s). If omitted, it defaults to the calling class.
1867              
1868             =item C<types ARRAYREF>
1869              
1870             A reference to an array of column method types to be created. If omitted, it defaults to the list of column method types returned by L<auto_method_types|/auto_method_types>.
1871              
1872             =back
1873              
1874             If any of the methods could not be created for any reason, a fatal error will occur.
1875              
1876             =item B<manager_uses_method [BOOL]>
1877              
1878             If true, then L<Rose::DB::Object::QueryBuilder> will pass column values through the object method(s) associated with this column when composing SQL queries where C<query_is_sql> is not set. The default value is false. See the L<Rose::DB::Object::QueryBuilder> documentation for more information.
1879              
1880             Note: the method is named "manager_uses_method" instead of, say, "query_builder_uses_method" because L<Rose::DB::Object::QueryBuilder> is rarely used directly. Instead, it's mostly used indirectly through the L<Rose::DB::Object::Manager> class.
1881              
1882             =item B<method_name TYPE [, NAME]>
1883              
1884             Get or set the name of the column method of type TYPE.
1885              
1886             =item B<mutator_method_name>
1887              
1888             Returns the name of the method used to set the column value. This is a convenient shortcut for:
1889              
1890             $column->method_name('set') || $column->method_name('get_set');
1891              
1892             =item B<name [NAME]>
1893              
1894             Get or set the name of the column, not including the table name, username, schema, or any other qualifier.
1895              
1896             =item B<nonpersistent [BOOL]>
1897              
1898             Get or set a boolean flag that indicates whether or not the column
1899             is L<non-persistent|Rose::DB::Object::Metadata/nonpersistent_columns>.
1900              
1901             =item B<not_null [BOOL]>
1902              
1903             Get or set a boolean flag that indicates whether or not the column
1904             value can be null.
1905              
1906             =item B<parse_value DB, VALUE>
1907              
1908             Parse and return a convenient Perl representation of VALUE. What form this value will take is up to the column subclass. If VALUE is a keyword or otherwise has special meaning to the underlying database, it may be returned unmodified. DB is a L<Rose::DB> object that may be used as part of the parsing process. Both arguments are required.
1909              
1910             =item B<primary_key_position [INT]>
1911              
1912             Get or set the column's ordinal position in the primary key. Returns undef if the column is not part of the primary key. Position numbering starts from 1.
1913              
1914             =item B<remarks [TEXT]>
1915              
1916             Get or set a text description of the column.
1917              
1918             =item B<rw_method_name>
1919              
1920             Returns the name of the method used to get or set the column value. This is a convenient shortcut for:
1921              
1922             $column->method_name('get_set');
1923              
1924             =item B<should_inline_value DB, VALUE>
1925              
1926             Given the L<Rose::DB>-derived object DB and the column value VALUE, return true of the value should be "inlined" (i.e., not bound to a "?" placeholder and passed as an argument to L<DBI>'s L<execute|DBI/execute> method), false otherwise. The default implementation always returns false.
1927              
1928             This method is necessary because some L<DBI> drivers do not (or cannot) always do the right thing when binding values to placeholders in SQL statements. For example, consider the following SQL for the Informix database:
1929              
1930             CREATE TABLE test (d DATETIME YEAR TO SECOND);
1931             INSERT INTO test (d) VALUES (CURRENT);
1932              
1933             This is valid Informix SQL and will insert a row with the current date and time into the "test" table.
1934              
1935             Now consider the following attempt to do the same thing using L<DBI> placeholders (assume the table was already created as per the CREATE TABLE statement above):
1936              
1937             $sth = $dbh->prepare('INSERT INTO test (d) VALUES (?)');
1938             $sth->execute('CURRENT'); # Error!
1939              
1940             What you'll end up with is an error like this:
1941              
1942             DBD::Informix::st execute failed: SQL: -1262: Non-numeric
1943             character in datetime or interval.
1944              
1945             In other words, L<DBD::Informix> has tried to quote the string "CURRENT", which has special meaning to Informix only when it is not quoted.
1946              
1947             In order to make this work, the value "CURRENT" must be "inlined" rather than bound to a placeholder when it is the value of a "DATETIME YEAR TO SECOND" column in an Informix database.
1948              
1949             All of the information needed to make this decision is available to the call to L<should_inline_value|/should_inline_value>. It gets passed a L<Rose::DB>-derived object, from which it can determine the database driver, and it gets passed the actual value, which it can check to see if it matches C</^current$/i>.
1950              
1951             This is just one example. Each subclass of L<Rose::DB::Object::Metadata::Column> must determine for itself when a value needs to be inlined.
1952              
1953             =item B<triggers EVENT [, CODEREF | ARRAYREF ]>
1954              
1955             Get or set the list of trigger subroutines for EVENT. Valid event names are C<on_get>, C<on_set>, C<on_load>, C<on_save>, C<inflate>, and C<deflate>. See the L<triggers|/TRIGGERS> section of this documentation for more information on these event types.
1956              
1957             If passed a code ref or a reference to an array of code refs, then the list of trigger subroutines for EVENT is replaced with those code ref(s).
1958              
1959             Returns a reference to an array of trigger subroutines for the event type EVENT. If there are no triggers for EVENT, undef will be returned.
1960              
1961             =item B<triggers_disabled>
1962              
1963             Returns true if L<triggers|/TRIGGERS> are disabled for this column, false otherwise.
1964              
1965             =item B<type>
1966              
1967             Returns the (possibly abstract) data type of the column. The default implementation returns "scalar".
1968              
1969             =item B<undef_overrides_default [BOOL]>
1970              
1971             Get or set a boolean value that indicates whether or not setting the column to an undef value overrides the column's L<default|/default> value.
1972              
1973             The default value of this attribute is determined by the parent L<metadata|Rose::DB::Object::Metadata> object's L<column_undef_overrides_default|Rose::DB::Object::Metadata/column_undef_overrides_default> method, or the column's L<default_undef_overrides_default|/default_undef_overrides_default> class method id the metadata object's L<column_undef_overrides_default|Rose::DB::Object::Metadata/column_undef_overrides_default> method returns undef, or if the column has no parent metadata object.
1974              
1975             Example: consider a L<Rose::DB::Object>-derived C<Person> class with a C<name> column set up like this:
1976              
1977             package Person;
1978             ...
1979             columns =>
1980             [
1981             name => { type => 'varchar', default => 'John Doe' },
1982             ...
1983             ],
1984             ...
1985              
1986             The following behavior is the same regardless of the setting of the L<undef_overrides_default|/undef_overrides_default> attribute for the C<name> column:
1987              
1988             $p = Person->new;
1989             print $p->name; # John Doe
1990              
1991             $p->name('Larry Wall');
1992             print $p->name; # Larry Wall
1993              
1994             If L<undef_overrides_default|/undef_overrides_default> is B<false> for the C<name> column, then this is the behavior of explicitly setting the column to undef:
1995              
1996             $p->name(undef);
1997             print $p->name; # John Doe
1998              
1999             If L<undef_overrides_default|/undef_overrides_default> is B<true> for the C<name> column, then this is the behavior of explicitly setting the column to undef:
2000              
2001             $p->name(undef);
2002             print $p->name; # undef
2003              
2004             The L<undef_overrides_default|/undef_overrides_default> attribute can be set directly on the column:
2005              
2006             name => { type => 'varchar', default => 'John Doe',
2007             undef_overrides_default => 1 },
2008              
2009             or it can be set class-wide using the L<meta|Rose::DB::Object/meta> object's L<column_undef_overrides_default|Rose::DB::Object::Metadata/column_undef_overrides_default> attribute:
2010              
2011             Person->meta->column_undef_overrides_default(1);
2012              
2013             or it can be set for all classes that use a given L<Rose::DB::Object::Metadata>-derived class using the L<default_column_undef_overrides_default|Rose::DB::Object::Metadata/default_column_undef_overrides_default> class method:
2014              
2015             My::DB::Object::Metadata->default_column_undef_overrides_default(1);
2016              
2017             =back
2018              
2019             =head1 PROTECTED API
2020              
2021             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::Column>, 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.
2022              
2023             =over 4
2024              
2025             =item B<method_maker_arguments TYPE>
2026              
2027             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 column method type TYPE.
2028              
2029             =item B<method_maker_class TYPE [, CLASS]>
2030              
2031             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.
2032              
2033             Returns the name of the L<Rose::Object::MakeMethods>-derived class used to create the object method of type TYPE.
2034              
2035             =item B<method_maker_type TYPE [, NAME]>
2036              
2037             If NAME is passed, the name of the method maker method type for the column method type TYPE is set to NAME.
2038              
2039             Returns the method maker method type for the column method type TYPE.
2040              
2041             =back
2042              
2043             =head1 AUTHOR
2044              
2045             John C. Siracusa (siracusa@gmail.com)
2046              
2047             =head1 LICENSE
2048              
2049             Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is
2050             free software; you can redistribute it and/or modify it under the same terms
2051             as Perl itself.