File Coverage

blib/lib/KiokuDB/Backend/Serialize/JSPON/Collapser.pm
Criterion Covered Total %
statement 39 39 100.0
branch 35 38 92.1
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 82 85 96.4


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package KiokuDB::Backend::Serialize::JSPON::Collapser;
4 6     6   31 use Moose;
  6         9  
  6         45  
5              
6 6     6   31528 use KiokuDB::Entry;
  6         12  
  6         124  
7 6     6   26 use KiokuDB::Reference;
  6         13  
  6         102  
8 6     6   1317 use JSON;
  6         17746  
  6         51  
9              
10 6     6   989 use namespace::clean -except => 'meta';
  6         12  
  6         61  
11              
12             with qw(KiokuDB::Backend::Serialize::JSPON::Converter);
13              
14             has reserved_key => (
15             isa => "RegexpRef",
16             is => "ro",
17             lazy_build => 1,
18             );
19              
20             sub _build_reserved_key {
21 19     19   34 my $self = shift;
22              
23 19         78 my $reserved = '^(?:' . join("|", map { quotemeta($self->$_) } map { $_ . "_field" } $self->_jspon_fields) . ')$';
  190         6171  
  190         245  
24              
25 19         1267 qr/(?: $reserved | ^public:: )/x
26             }
27              
28             sub collapse_jspon {
29 4380     4380 1 12265 my ( $self, $data ) = @_;
30              
31 4380 100       7963 if ( my $ref = ref $data ) {
32 4332 100       10089 if ( $ref eq 'KiokuDB::Reference' ) {
    100          
    100          
    50          
33             return {
34 973 100       32806 $self->ref_field => $data->id . ( $self->inline_data ? "" : "." . $self->data_field ),
    100          
35             ( $data->is_weak ? ( weak => 1 ) : () ),
36             };
37             } elsif ( $ref eq 'KiokuDB::Entry' ) {
38 797         19288 my $id = $data->id;
39              
40             return {
41 1         24 ( $data->has_class ? ( $self->class_field => $data->class ) : () ),
42             ( $data->has_class_meta ? ( $self->class_meta_field => $data->class_meta ) : () ),
43             ( defined $data->class_version ? ( $self->class_version_field => $data->class_version ) : () ),
44             ( $id ? ( $self->id_field => $id ) : () ),
45             ( $data->root ? ( $self->root_field => JSON::true() ) : () ),
46             ( $data->deleted ? ( $self->deleted_field => JSON::true() ) : () ),
47             ( $data->has_tied ? ( $self->tied_field => $data->tied ) : () ),
48             ( defined $data->backend_data ? ( $self->backend_data_field => $data->backend_data ) : () ),
49             ( $self->inline_data
50 797 100       21923 ? %{ $self->collapse_jspon($data->data) }
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
51             : ( $self->data_field => $self->collapse_jspon($data->data) )
52             ),
53             };
54             } elsif ( $ref eq 'HASH' ) {
55 735         1104 my %hash;
56 735         25092 my $res = $self->reserved_key;
57              
58 735         2944 foreach my $key ( keys %$data ) {
59 2982         3565 my $value = $data->{$key};
60 2982 100       5750 my $collapsed = ref($value) ? $self->collapse_jspon($value) : $value;
61              
62 2982 100       9447 if ( $key =~ $res ) {
63 31         99 $hash{"public::$key"} = $collapsed;
64             } else {
65 2951         5807 $hash{$key} = $collapsed;
66             }
67             }
68              
69 735         6100 return \%hash;
70             } elsif ( $ref eq 'ARRAY' ) {
71 1827 100       3264 return [ map { ref($_) ? $self->collapse_jspon($_) : $_ } @$data ];
  882         2485  
72             }
73             }
74              
75 48         309 return $data;
76             }
77              
78             __PACKAGE__->meta->make_immutable;
79              
80             __PACKAGE__
81              
82             __END__
83              
84             =pod
85              
86             =head1 NAME
87              
88             KiokuDB::Backend::Serialize::JSPON::Collapser - Collapse entry data to
89             JSPON compliant structures
90              
91             =head1 SYNOPSIS
92              
93             my $c = KiokuDB::Backend::Serialize::JSPON::Collapser->new(
94             id_field => "_id",
95             );
96              
97             my $hashref = $c->collapse_jspon($entry);
98              
99             =head1 DESCRIPTION
100              
101             This object is used by L<KiokuDB::Backend::Serialize::JSPON> to convert
102             L<KiokuDB::Entry> objects to JSPON compliant structures.
103              
104             =head1 ATTRIBUTES
105              
106             See L<KiokuDB::Backend::Serialize::JSPON::Converter> for attributes shared by
107             L<KiokuDB::Backend::Serialize::JSPON::Collapser> and
108             L<KiokuDB::Backend::Serialize::JSPON::Expander>.
109              
110             =head1 METHODS
111              
112             =over 4
113              
114             =item collapse_jspon $entry
115              
116             Collapses the entry recursively, returning a JSPON compliant data structure
117             suitable for serialization as a JSON string.
118              
119             =back
120              
121             =cut
122