File Coverage

blib/lib/DBIx/Class/HashAccessor.pm
Criterion Covered Total %
statement 113 117 96.5
branch 47 84 55.9
condition 4 12 33.3
subroutine 14 14 100.0
pod 0 1 0.0
total 178 228 78.0


line stmt bran cond sub pod time code
1             package DBIx::Class::HashAccessor;
2             our $AUTHORITY = 'cpan:GETTY';
3             # ABSTRACT: Helper functions to install accessors for serialized hash columns
4             $DBIx::Class::HashAccessor::VERSION = '0.001';
5 2     2   93895 use strict;
  2         4  
  2         47  
6 2     2   8 use warnings;
  2         4  
  2         40  
7 2     2   235 use Package::Stash;
  2         5460  
  2         46  
8              
9 2     2   256 use parent 'DBIx::Class::Row';
  2         216  
  2         9  
10              
11             sub add_hash_accessor {
12 1     1 0 62372 my ( $class, $accessor, $hash ) = @_;
13 1 50 33     9 die 'require accessor and hash name' unless defined $accessor and defined $hash;
14 1 50       4 die 'accessor can\'t be named like hash' if $accessor eq $hash;
15 1         8 my $st = Package::Stash->new($class);
16              
17             $st->add_symbol('&'.$accessor,sub {
18 5     5   352321 my ( $self, @args ) = @_;
19 5 50       23 die((ref $self).' does not support '.$hash) unless $self->can($hash);
20 5 100       8 my %h = %{$self->$hash || {}};
  5         107  
21 5 100       217 if (scalar @args == 1) {
    50          
22 4         23 return $h{$args[0]};
23             } elsif (scalar @args == 2) {
24 1         4 $h{$args[0]} = $args[1];
25 1         25 $self->$hash({ %h });
26 1         377 return $args[1];
27             } else {
28 0         0 die $accessor.' function must get 1 or 2 args';
29             }
30 1         29 });
31              
32             $st->add_symbol('&'.$accessor.'_hash',sub {
33 3     3   9 my ( $self, $key, @args ) = @_;
34 3 50       13 die((ref $self).' does not support '.$hash) unless $self->can($hash);
35 3 50       4 my %h = %{$self->$hash || {}};
  3         65  
36 3 100       90 if (scalar @args == 1) {
    50          
37 2 50       14 return ref $h{$key} eq 'HASH' ? $h{$key}->{$args[0]} : undef;
38             } elsif (scalar @args == 2) {
39 1 50       6 $h{$key} = {} unless exists $h{$key};
40 1 50       5 return undef unless ref $h{$key} eq 'HASH';
41 1         4 $h{$key}->{$args[0]} = $args[1];
42 1         19 $self->$hash({ %h });
43 1         79 return $args[1];
44             } else {
45 0         0 die $accessor.'_hash function must get 2 or 3 args';
46             }
47 1         11 });
48              
49             $st->add_symbol('&'.$accessor.'_hash_delete',sub {
50 1     1   4 my ( $self, $key, $hash_key ) = @_;
51 1 50       6 die((ref $self).' does not support '.$hash) unless $self->can($hash);
52 1 50       2 my %h = %{$self->$hash || {}};
  1         23  
53 1 50 33     31 if ($key && $hash_key) {
54 1 50       4 return undef unless ref $h{$key} eq 'HASH';
55 1         4 my $old_value = delete $h{$key}->{$hash_key};
56 1         19 $self->$hash({ %h });
57 1         82 return $old_value;
58             } else {
59 0         0 die $accessor.'_hash_delete function must get 2 args';
60             }
61 1         11 });
62              
63             $st->add_symbol('&'.$accessor.'_push',sub {
64 1     1   4 my ( $self, $key, @elements ) = @_;
65 1 50       6 die((ref $self).' does not support '.$hash) unless $self->can($hash);
66 1 50       3 die $accessor.'_push function requires 1 arg' unless defined $key;
67 1 50       2 my %h = %{$self->$hash || {}};
  1         21  
68 1 50       29 my @array = defined $h{$key} ? ( @{$h{$key}} ) : ();
  0         0  
69 1         9 push @array, @elements;
70 1         3 $h{$key} = [ @array ];
71 1         20 $self->$hash({ %h });
72 1         83 return @elements;
73 1         10 });
74              
75             $st->add_symbol('&'.$accessor.'_shift',sub {
76 1     1   4 my ( $self, $key ) = @_;
77 1 50       5 die((ref $self).' does not support '.$hash) unless $self->can($hash);
78 1 50       4 die $accessor.'_shift function requires 1 arg' unless defined $key;
79 1 50       2 my %h = %{$self->$hash || {}};
  1         23  
80 1 50       32 my @array = defined $h{$key} ? ( @{$h{$key}} ) : ();
  1         4  
81 1 50       11 return unless scalar @array;
82 1         2 my $return = shift @array;
83 1         3 $h{$key} = [ @array ];
84 1         23 $self->$hash({ %h });
85 1         80 return $return;
86 1         11 });
87              
88             $st->add_symbol('&'.$accessor.'_in',sub {
89 2     2   6 my ( $self, $key, $val ) = @_;
90 2 50       10 die((ref $self).' does not support '.$hash) unless $self->can($hash);
91 2 50 33     10 die $accessor.'_in function requires 2 args' unless defined $val && defined $key;
92 2 50       4 my %h = %{$self->$hash || {}};
  2         44  
93 2 50       54 my @array = defined $h{$key} ? ( @{$h{$key}} ) : ();
  2         6  
94 2         4 for (@array) {
95 3 100       13 return 1 if $val eq $_;
96             }
97 1         5 return 0;
98 1         15 });
99              
100             $st->add_symbol('&'.$accessor.'_in_delete',sub {
101 1     1   4 my ( $self, $key, $val ) = @_;
102 1 50       5 die((ref $self).' does not support '.$hash) unless $self->can($hash);
103 1 50 33     7 die $accessor.'_in_delete function requires 2 args' unless defined $val && defined $key;
104 1 50       2 my %h = %{$self->$hash || {}};
  1         21  
105 1 50       29 my @array = defined $h{$key} ? ( @{$h{$key}} ) : ();
  1         4  
106 1         2 my @new_array;
107 1         3 for my $old_val (@array) {
108 2 100       8 push @new_array, $old_val unless $val eq $old_val;
109             }
110 1         4 $h{$key} = [ @new_array ];
111 1         20 $self->$hash({ %h });
112 1         81 return;
113 1         51 });
114              
115             $st->add_symbol('&'.$accessor.'_delete',sub {
116 1     1   11 my ( $self, $key ) = @_;
117 1 50       8 die((ref $self).' does not support '.$hash) unless $self->can($hash);
118 1 50       4 die $accessor.'_delete function requires 1 arg' unless defined $key;
119 1 50       2 my %h = %{$self->$hash || {}};
  1         23  
120 1         28 my $return = delete $h{$key};
121 1         19 $self->$hash({ %h });
122 1         82 return $return;
123 1         10 });
124              
125             $st->add_symbol('&'.$accessor.'_exists',sub {
126 4     4   11 my ( $self, $key ) = @_;
127 4 50       19 die((ref $self).' does not support '.$hash) unless $self->can($hash);
128 4 50       11 die $accessor.'_exists function requires 1 arg' unless defined $key;
129 4 50       18 my %h = %{$self->$hash || {}};
  4         86  
130 4         113 return exists $h{$key};
131 1         20 });
132              
133             }
134              
135             1;
136              
137             __END__