File Coverage

blib/lib/App/RecordStream/Operation/frommongo.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package App::RecordStream::Operation::frommongo;
2              
3             our $VERSION = "4.0.25";
4              
5 1     1   370 use strict;
  1         2  
  1         21  
6 1     1   4 use warnings;
  1         2  
  1         19  
7              
8 1     1   3 use base qw(App::RecordStream::Operation);
  1         2  
  1         71  
9              
10 1     1   150 use MongoDB;
  0            
  0            
11             use Data::Dumper;
12             use JSON::PP;
13              
14             sub init {
15             my $this = shift;
16             my $args = shift;
17              
18             my ($host, $user, $pass, $db_name, $query, $collection);
19              
20             my $spec = {
21             "host=s" => \$host,
22             "user=s" => \$user,
23             "password|pass=s" => \$pass,
24             "name|dbname=s" => \$db_name,
25             "query=s" => \$query,
26             "collection=s" => \$collection,
27             };
28              
29             $this->parse_options($args, $spec);
30              
31             unless(defined $host && defined $db_name && defined $query && defined $collection) {
32             die "Must specify all of --host, --name, --collection, and --query\n";
33             }
34              
35             my $params = {
36             host => $host,
37             db_name => $db_name,
38             };
39              
40             $params->{'username'} = $user if defined $user;
41             $params->{'password'} = $pass if defined $pass;
42              
43             # This will come closer to allowing mongo-hq style json
44             my $json = JSON::PP->new()
45             ->allow_barekey() # Allow {navItem:[]} instead of {'navItem':[]}
46             ->allow_singlequote() # allow single quotes for keys
47             ->relaxed(1); # Allow trailing commas and comments in strings
48              
49             $this->{'CONNECT_PARAMS'} = $params;
50             $this->{'DB_NAME'} = $db_name;
51             $this->{'COLLECTION'} = $collection;
52             $this->{'QUERY'} = $json->decode($query);
53             }
54              
55             sub wants_input {
56             return 0;
57             }
58              
59             sub stream_done {
60             my $this = shift;
61              
62             my $cursor = $this->get_query();
63              
64             while (my $object = $cursor->next()) {
65             $this->push_record($object);
66             }
67             }
68              
69             sub get_query {
70             my $this = shift;
71              
72             # this momoization is really just a hook for tests
73             if ($this->{'CURSOR'}) {
74             return $this->{'CURSOR'};
75             }
76              
77             # Initialize client here, otherwise authorization errors will also show usage
78             my $client = MongoDB::MongoClient->new(
79             %{$this->{'CONNECT_PARAMS'}},
80             );
81              
82             my $db = $client->get_database($this->{'DB_NAME'});
83             my $collection = $db->get_collection($this->{'COLLECTION'});
84             return $this->{'CURSOR'} = $collection->find($this->{'QUERY'});
85             }
86              
87             sub usage {
88             my $this = shift;
89              
90             my $options = [
91             [ 'host ', 'URI for your mongo instance, may include user:pass@URI'],
92             [ 'user ', 'User to authenticate as.'],
93             [ 'password ', 'Password for --user'],
94             [ 'name ', 'Name of database to connect to'],
95             [ 'collection ', 'Name of collection to query against'],
96             [ 'query ', 'JSON query string to run against the --collection'],
97             ];
98              
99             my $args_string = $this->options_string($options);
100              
101             return <
102             recs-frommongo --host user:pass\@URI --name DB_NAME --collection COLLECTION --query QUERY
103             __FORMAT_TEXT__
104             Generate records from a MongoDB query.
105             __FORMAT_TEXT__
106              
107             Arguments:
108             $args_string
109              
110             Examples:
111             Make a query against mongo hq
112             recs-frommongo --host mongodb://user:pass\@dharma.mongohq.com:10069 --name my_app --collection my_collection --query '{doc_key: {\$not: {\$size: 0}}}'
113              
114             USAGE
115             }
116              
117             1;