File Coverage

blib/lib/Mojo/Util/Model.pm
Criterion Covered Total %
statement 29 48 60.4
branch 5 20 25.0
condition 4 10 40.0
subroutine 5 7 71.4
pod 4 4 100.0
total 47 89 52.8


line stmt bran cond sub pod time code
1             package Mojo::Util::Model;
2 32     32   271 use Mojo::Base -base;
  32         66  
  32         208  
3              
4             our $VERSION = '0.0.19';
5              
6 32     32   25198 use Mojo::JSON qw(encode_json);
  32         7892785  
  32         43310  
7              
8             has 'exists' => sub {
9             return shift->pk ? 1 : 0;
10             };
11              
12             has 'id';
13              
14             has 'keys_to_serialize' => sub {
15             my $self = shift;
16              
17             my @keys = keys(%$self);
18              
19             push(@keys, 'exists', 'pk', 'primary_key');
20              
21             return \@keys;
22             };
23              
24             has 'pk' => sub {
25             my $self = shift;
26              
27             return $self->get($self->primary_key);
28             };
29              
30             has 'primary_key' => 'id';
31              
32             =head2 get
33              
34             Returns the value of a field.
35              
36             =cut
37              
38             sub get {
39 339     339 1 1578 my ($self, $field, $default) = @_;
40              
41 339         547 my $value = undef;
42 339   100     1463 $default //= undef;
43              
44 339         770 my @pieces = split(/\./, $field);
45              
46 339 50       858 if (scalar(@pieces) > 1) {
47 0         0 $field = shift @pieces;
48              
49 0 0       0 if ($self->can($field)) {
50 0 0       0 if (ref($self->$field) eq 'HASH') {
51 0         0 my $tmp = $self->$field;
52              
53 0         0 while (ref($tmp) eq 'HASH') {
54 0         0 $field = shift @pieces;
55 0         0 $tmp = $tmp->{ $field };
56             }
57              
58 0   0     0 return $tmp || $default;
59             }
60              
61 0         0 return $self->$field->get(join('.', @pieces), $default);
62             }
63              
64 0         0 return $default;
65             }
66              
67 339 50       1386 if ($self->can($field)) {
68 339         920 $value = $self->$field;
69             } else {
70 0 0       0 $value = $self->{ $field } if (exists $self->{ $field });
71             }
72              
73 339   33     2917 return $value // $default;
74             }
75              
76             =head2 serialize
77              
78             Returns a hashref representation of the model.
79              
80             =cut
81              
82             sub serialize {
83 16     16 1 24 my $self = shift;
84              
85 16         31 my @fields = @_;
86              
87 16 100       34 if (!scalar(@fields)) {
88 8         13 @fields = @{ $self->keys_to_serialize };
  8         75  
89             }
90              
91 16         26 my $result = {};
92              
93 16         44 $result->{ $_ } = $self->get($_) for (@fields);
94              
95 16         79 return $result;
96             }
97              
98             =head2 toCsv
99              
100             Returns a CSV representation of the model.
101              
102             =cut
103              
104             sub toCsv {
105 4     4 1 15 my ($self, $columns, $options) = @_;
106              
107 4 50       10 my $default = defined($options->{ default }) ? $options->{ default } : 'n/a';
108 4   50     11 my $quote_char = $options->{ quote_char } // '"';
109              
110 4         4 my @array;
111              
112 4         8 foreach my $column (@$columns) {
113 12         38 push(@array, sprintf('%s%s%s', $quote_char, $self->get($column, $default), $quote_char));
114             }
115              
116 4         16 return join(',', @array);
117             }
118              
119             =head2 toJson
120              
121             Returns a JSON representation of the model.
122              
123             =cut
124              
125             sub toJson {
126 0     0 1   return encode_json(shift->serialize);
127             }
128              
129             =head2 AUTOLOAD
130              
131             Try to get a field from the model or die.
132              
133             =cut
134              
135             sub AUTOLOAD {
136 0     0     my $self = shift;
137 0           our $AUTOLOAD;
138 0 0         my $field = $AUTOLOAD =~ /::(\w+)$/ ? $1 : undef;
139              
140 0           $field =~ s/.*:://;
141 0 0         return unless $field =~ /[^A-Z]/; # skip DESTROY and all-cap methods
142              
143 0 0         return $self->get($field) if (exists $self->{ $field });
144              
145 0           die "Undefined method $AUTOLOAD";
146             }
147              
148             1;