File Coverage

blib/lib/Catmandu/Cmd/copy.pm
Criterion Covered Total %
statement 32 40 80.0
branch 8 20 40.0
condition 2 6 33.3
subroutine 7 7 100.0
pod 2 2 100.0
total 51 75 68.0


line stmt bran cond sub pod time code
1             package Catmandu::Cmd::copy;
2              
3 14     14   133075 use Catmandu::Sane;
  14         50  
  14         91  
4              
5             our $VERSION = '1.2020';
6              
7 14     14   108 use parent 'Catmandu::Cmd';
  14         36  
  14         80  
8 14     14   1030 use Catmandu;
  14         43  
  14         75  
9 14     14   2964 use namespace::clean;
  14         43  
  14         84  
10              
11             sub command_opt_spec {
12             (
13 1     1 1 45 ["verbose|v", ""],
14             ["fix=s@", ""],
15             ["var=s%", ""],
16             ["preprocess|pp", ""],
17             ["start=i", ""],
18             ["limit=i", ""],
19             ["total=i", ""],
20             ["cql-query|q=s", ""],
21             ["query=s", ""],
22             ["sru-sortkeys=s", ""],
23             ["sort=s", ""],
24             ["delete", "delete existing items first"],
25             ["transaction|tx", "wrap in a transaction"],
26             );
27             }
28              
29             sub command {
30 1     1 1 4 my ($self, $opts, $args) = @_;
31              
32 1         6 my ($from_args, $from_opts, $into_args, $into_opts)
33             = $self->_parse_options($args);
34              
35 1         5 my $from_bag = delete $from_opts->{bag};
36 1         8 my $from = Catmandu->store($from_args->[0], $from_opts)->bag($from_bag);
37 1         8 my $into_bag = delete $into_opts->{bag};
38 1         8 my $into = Catmandu->store($into_args->[0], $into_opts)->bag($into_bag);
39              
40 1 50 33     23 if ($opts->query // $opts->cql_query) {
    50 33        
41 0 0       0 $self->usage_error("Bag isn't searchable")
42             unless $from->can('searcher');
43 0         0 $from = $from->searcher(
44             cql_query => $opts->cql_query,
45             query => $opts->query,
46             start => $opts->start,
47             total => $opts->total,
48             limit => $opts->limit,
49             );
50             }
51             elsif ($opts->start // $opts->total) {
52 0         0 $from = $from->slice($opts->start, $opts->total);
53             }
54 1 50       36 if ($opts->fix) {
55 0         0 $from = $self->_build_fixer($opts)->fix($from);
56             }
57 1 50       9 if ($opts->verbose) {
58 1         11 $from = $from->benchmark;
59             }
60              
61             my $tx = sub {
62 1 50   1   6 if ($opts->delete) {
63 0         0 $into->delete_all;
64 0         0 $into->commit;
65             }
66              
67 1         14 my $n = $into->add_many($from);
68 1         22 $into->commit;
69 1 50       5 if ($opts->verbose) {
70 1 50       18 say STDERR $n == 1 ? "copied 1 item" : "copied $n items";
71 1         30 say STDERR "done";
72             }
73 1         18 };
74              
75 1 50       8 if ($opts->transaction) {
76 0 0       0 $self->usage_error("Bag isn't transactional")
77             if !$into->store->does('Catmandu::Transactional');
78 0         0 $into->store->transaction($tx);
79             }
80             else {
81 1         6 $tx->();
82             }
83             }
84              
85             1;
86              
87             __END__
88              
89             =pod
90              
91             =head1 NAME
92              
93             Catmandu::Cmd::copy - copy items from one store to another
94              
95             =head1 EXAMPLES
96              
97             catmandu copy <STORE> <OPTIONS> to <STORE> <OPTIONS>
98              
99             catmandu copy MongoDB --database_name items --bag book to \
100             ElasticSearch --index_name items --bag book
101              
102             catmandu help store MongoDB
103             catmandu help store ElasticSearch
104              
105             =cut