File Coverage

blib/lib/Mango/BSON/Dump.pm
Criterion Covered Total %
statement 32 37 86.4
branch 4 4 100.0
condition 1 2 50.0
subroutine 16 17 94.1
pod 1 1 100.0
total 54 61 88.5


line stmt bran cond sub pod time code
1              
2             package Mango::BSON::Dump;
3             $Mango::BSON::Dump::VERSION = '0.1';
4             # ABSTRACT: Helpers to dump Mango BSON documents as Extended JSON
5              
6 2     2   92871 use 5.010;
  2         6  
7 2     2   380 use Mojo::Base -strict;
  2         7470  
  2         12  
8              
9 2     2   642 use Mango::BSON ();
  2         60674  
  2         29  
10 2     2   9 use Mojo::Util ();
  2         3  
  2         24  
11 2     2   7 use re (); # regexp_pattern()
  2         2  
  2         20  
12 2     2   1232 use JSON::XS ();
  2         7418  
  2         51  
13              
14 2     2   9 use Exporter 5.57 'import';
  2         20  
  2         927  
15             our @EXPORT_OK = qw(to_extjson);
16              
17             sub to_extjson {
18 0     0 1 0 my $doc = shift;
19 0         0 state $encoder = JSON::XS->new->convert_blessed(1);
20 0         0 my %opts = (pretty=>0,@_);
21 0         0 $encoder->$_($opts{$_}) for qw(pretty);
22 0         0 return $encoder->encode($doc) . "\n";
23             }
24              
25             our %BINTYPE_MAP = (
26             'generic' => Mango::BSON::BINARY_GENERIC(),
27             'function' => Mango::BSON::BINARY_FUNCTION(),
28             'md5' => Mango::BSON::BINARY_MD5(),
29             'uuid' => Mango::BSON::BINARY_UUID(),
30             'user_defined' => Mango::BSON::BINARY_USER_DEFINED(),
31             );
32              
33             my %TO_EXTJSON = (
34              
35             # bson_bin
36             'Mango::BSON::Binary' => sub {
37 1     1   771 my $bindata = Mojo::Util::b64_encode( $_[0]->data, '' );
38 1   50     41 my $type = unpack( "H2", $BINTYPE_MAP{ $_[0]->type // 'generic' } );
39 1         20 { '$binary' => $bindata, '$type' => $type };
40             },
41              
42             # bson_code
43             'Mango::BSON::Code' => sub {
44 2 100   2   937 $_[0]->scope
45             ? { '$code' => $_[0]->code, '$scope' => $_[0]->scope }
46             : { '$code' => $_[0]->code };
47             },
48              
49             # bson_double
50             # bson_int32
51             # bson_int64
52             'Mango::BSON::Number' => sub {
53 3 100   3   1100 ( $_[0]->type eq Mango::BSON::INT64() )
54             ? { '$numberLong' => $_[0]->to_string }
55             : $_[0]->value + 0 # DOUBLE() or INT32()
56             },
57              
58             # bson_max
59             'Mango::BSON::_MaxKey' => sub {
60 1     1   360 { '$maxKey' => 1 };
61             },
62              
63             # bson_min
64             'Mango::BSON::_MinKey' => sub {
65 1     1   366 { '$minKey' => 1 };
66             },
67              
68             # bson_oid
69             'Mango::BSON::ObjectID' => sub {
70 2     2   697 { '$oid' => $_[0]->to_string };
71             },
72              
73             # bson_time
74             'Mango::BSON::Time' => sub {
75              
76             # {'$date' => {'$numberLong' => $_[0]->to_string . ''}}
77 1     1   377 { '$date' => $_[0]->to_datetime };
78             },
79              
80             # bson_ts
81             'Mango::BSON::Timestamp' => sub {
82 1     1   446 { '$timestamp' => { 't' => $_[0]->seconds, 'i' => $_[0]->increment } };
83             },
84              
85             # regex
86             'Regexp' => sub {
87 1     1   1095 my ( $p, $m ) = re::regexp_pattern( $_[0] );
88 1         8 { '$regex' => $p, '$options' => $m };
89             },
90              
91             );
92              
93             # Don't need TO_EXTJSON:
94             # bson_doc
95             # bson_dbref
96             # bson_true
97             # bson_false
98              
99             for my $class ( keys %TO_EXTJSON ) {
100             my $patch = $TO_EXTJSON{$class};
101             Mojo::Util::monkey_patch( $class, TO_JSON => $patch );
102             }
103              
104             1;
105              
106             =pod
107              
108             =encoding UTF-8
109              
110             =head1 NAME
111              
112             Mango::BSON::Dump - Helpers to dump Mango BSON documents as Extended JSON
113              
114             =head1 VERSION
115              
116             version 0.1
117              
118             =head1 SYNOPSIS
119              
120             use Mango::BSON ':bson';
121             use Mango::BSON::Dump qw(to_extjson);
122              
123             # '{"v":{"$numberLong":"42"},"created":{"$date":"1970-01-01T00:00:00Z"}}'
124             to_extjson(bson_doc(v => bson_int64(42), created => bson_time(0)));
125              
126             use Mojo::JSON qw(encode_json);
127              
128             # '{"v":{"$numberLong":"42"},"created":{"$date":"1970-01-01T00:00:00Z"}}'
129             encode_json(bson_doc(v => bson_int64(42), created => bson_time(0)));
130              
131             =head1 DESCRIPTION
132              
133             This module enables dumping Mango BSON documents and objects
134             as Extended JSON (see https://docs.mongodb.com/manual/reference/mongodb-extended-json/),
135             which might be handy for development and debugging.
136              
137             =head1 FUNCTIONS
138              
139             =over 4
140              
141             =item B
142              
143             $json = to_extjson($bson_doc);
144             $json = to_extjson($bson_doc, pretty => 1);
145              
146             Encodes C<$bson_doc> into Extended JSON.
147              
148             =back
149              
150             =head1 CAVEATS
151              
152             This module installs C methods to a number of packages
153             (eg. Mango::BSON::Number, Mango::BSON::ObjectID, Regexp).
154             This does not play well with other modules defining or installing
155             the same methods to the same classes.
156             As of Mango 1.29, this clashes with defined C
157             for Mango::BSON::Binary, Mango::BSON::Number, and Mango::BSON::Time
158             (which don't conform to Extended JSON).
159              
160             =head1 SEE ALSO
161              
162             https://docs.mongodb.com/manual/reference/mongodb-extended-json/
163              
164             https://docs.mongodb.com/manual/reference/bson-types/
165              
166             http://bsonspec.org/
167              
168             https://github.com/mongodb/specifications/tree/master/source/bson-corpus
169              
170             =head1 ACKNOWLEDGMENTS
171              
172             The development of this library has been partially sponsored by Connectivity, Inc.
173              
174             =head1 AUTHOR
175              
176             Adriano Ferreira
177              
178             =head1 COPYRIGHT AND LICENSE
179              
180             This software is copyright (c) 2016 by Adriano Ferreira.
181              
182             This is free software; you can redistribute it and/or modify it under
183             the same terms as the Perl 5 programming language system itself.
184              
185             =cut
186              
187             __END__