File Coverage

blib/lib/Couchbase/Client.pm
Criterion Covered Total %
statement 30 114 26.3
branch 0 44 0.0
condition 0 22 0.0
subroutine 10 16 62.5
pod 1 1 100.0
total 41 197 20.8


line stmt bran cond sub pod time code
1             package Couchbase::Client;
2              
3             BEGIN {
4 3     3   30796 require XSLoader;
5 3         7 our $VERSION = '1.0.3';
6 3         3908 XSLoader::load(__PACKAGE__, $VERSION);
7             }
8              
9 3     3   20 use strict;
  3         2  
  3         84  
10 3     3   12 use warnings;
  3         6  
  3         93  
11              
12 3     3   1037 use Couchbase::Client::Errors;
  3         11  
  3         298  
13 3     3   989 use Couchbase::Client::IDXConst;
  3         5  
  3         533  
14 3     3   1066 use Couchbase::Client::Return;
  3         8  
  3         156  
15              
16 3     3   1196 my $have_storable = eval "use Storable; 1;";
  3         5799  
  3         114  
17 3     3   7043 my $have_zlib = eval "use Compress::Zlib; 1;";
  3         185466  
  3         778  
18              
19 3     3   2243 use Array::Assign;
  3         1985  
  3         183  
20              
21             {
22 3     3   17 no warnings 'once';
  3         4  
  3         2650  
23             *gets = \&get;
24             *gets_multi = \&get_multi;
25             }
26              
27             #this function converts hash options for compression and serialization
28             #to something suitable for construct()
29              
30             sub _make_conversion_settings {
31 0     0     my ($arglist,$options) = @_;
32 0           my $flags = 0;
33              
34              
35 0   0       $arglist->[CTORIDX_MYFLAGS] ||= 0;
36              
37 0 0         if($options->{dereference_scalar_ref}) {
38 0           $arglist->[CTORIDX_MYFLAGS] |= fDEREF_RVPV;
39             }
40              
41 0 0         if(exists $options->{deconversion}) {
42 0 0         if(! delete $options->{deconversion}) {
43 0           return;
44             }
45             } else {
46 0           $flags |= fDECONVERT;
47             }
48              
49 0 0         if(exists $options->{compress_threshold}) {
50 0           my $compress_threshold = delete $options->{compress_threshold};
51 0 0 0       $compress_threshold =
52             (!$compress_threshold || $compress_threshold < 0)
53             ? 0 : $compress_threshold;
54 0           $arglist->[CTORIDX_COMP_THRESHOLD] = $compress_threshold;
55 0 0         if($compress_threshold) {
56 0           $flags |= fUSE_COMPRESSION;
57             }
58             }
59              
60 0           my $meth_comp;
61 0 0         if(exists $options->{compress_methods}) {
    0          
62 0           $meth_comp = delete $options->{compress_methods};
63             } elsif($have_zlib) {
64 0     0     $meth_comp = [ sub { ${$_[1]} = Compress::Zlib::memGzip(${$_[0]}) },
  0            
  0            
65 0     0     sub { ${$_[1]} = Compress::Zlib::memGunzip(${$_[0]}) }]
  0            
  0            
  0            
66             }
67              
68 0 0         if(defined $meth_comp) {
69 0           $arglist->[CTORIDX_COMP_METHODS] = $meth_comp;
70             }
71              
72 0           my $meth_serialize = 0;
73 0 0         if(exists $options->{serialize_methods}) {
74 0           $meth_serialize = delete $options->{serialize_methods};
75             }
76              
77 0 0 0       if($meth_serialize == 0 && $have_storable) {
78 0           $meth_serialize = [ \&Storable::freeze, \&Storable::thaw ];
79             }
80              
81 0 0         if($meth_serialize) {
82 0           $flags |= fUSE_STORABLE;
83 0           $arglist->[CTORIDX_SERIALIZE_METHODS] = $meth_serialize;
84             }
85              
86 0           $arglist->[CTORIDX_MYFLAGS] |= $flags;
87             }
88              
89             sub _MkCtorIDX {
90 0     0     my $opts = shift;
91              
92 0           my @arglist;
93 0 0         my $server = delete $opts->{server} or die "Must have server";
94 0           arry_assign_i(@arglist,
95             CTORIDX_SERVERS, $server,
96             CTORIDX_USERNAME, delete $opts->{username},
97             CTORIDX_PASSWORD, delete $opts->{password},
98             CTORIDX_BUCKET, delete $opts->{bucket});
99              
100 0           _make_conversion_settings(\@arglist, $opts);
101              
102 0   0       my $tmp = delete $opts->{io_timeout} ||
103             delete $opts->{select_timeout} ||
104             delete $opts->{connect_timeout} ||
105             delete $opts->{timeout};
106              
107 0   0       $tmp ||= 2.5;
108 0 0         $arglist[CTORIDX_TIMEOUT] = $tmp if defined $tmp;
109 0           $arglist[CTORIDX_NO_CONNECT] = delete $opts->{no_init_connect};
110              
111              
112 0 0         if(keys %$opts) {
113 0           warn sprintf("Unused keys (%s) in constructor",
114             join(", ", keys %$opts));
115             }
116 0           return \@arglist;
117             }
118              
119             my %RETRY_ERRORS = (
120             COUCHBASE_NETWORK_ERROR, 1,
121             COUCHBASE_CONNECT_ERROR, 1,
122             COUCHBASE_ETIMEDOUT, 1,
123             COUCHBASE_UNKNOWN_HOST, 1
124             );
125              
126             sub new {
127 0     0 1   my ($pkg,$opts) = @_;
128 0           my $server_list;
129 0 0         if($opts->{servers}) {
    0          
130 0           $server_list = delete $opts->{servers};
131 0 0         if(ref $server_list ne 'ARRAY') {
132 0           $server_list = [$server_list];
133             }
134             } elsif ($opts->{server}) {
135 0   0       $server_list = [ delete $opts->{server} or die "server is false" ];
136             } else {
137 0           die("Must have server or servers");
138             }
139              
140 0           my $connected_ok;
141 0           my $no_init_connect = $opts->{no_init_connect};
142 0           my $self;
143              
144             my @all_errors;
145              
146 0           my $privopts;
147 0   0       while(!$connected_ok && (my $server = shift @$server_list)) {
148 0           $opts->{server} = $server;
149 0           $privopts = {%$opts};
150 0           my $arglist = _MkCtorIDX($privopts);
151 0           $self = $pkg->construct($arglist);
152 0           my $errors = $self->get_errors;
153 0           my $error_retriable;
154 0 0         if(scalar @$errors) {
155 0           push @all_errors, @$errors;
156 0           foreach (@$errors) {
157 0           my ($errno,$errstr) = @$_;
158 0 0         if(exists $RETRY_ERRORS{$errno}) {
159 0           $error_retriable++;
160             }
161             }
162 0 0         if(!$error_retriable) {
163 0           last;
164             }
165             } else {
166 0           last;
167             }
168 0 0         if($no_init_connect) {
169 0           last;
170             }
171             }
172 0           @{$self->get_errors} = @all_errors;
  0            
173 0           return $self;
174              
175             }
176              
177             #This is called from within C to record our stats:
178             sub _stats_helper {
179 0     0     my ($hash,$server,$key,$data) = @_;
180             #printf("Got server %s, key%s\n", $server, $key);
181 0   0       $key ||= "__default__";
182 0   0       ($hash->{$server}->{$key} ||= "") .= $data;
183             }
184              
185             1;
186              
187             __END__