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 4     4   50361 require XSLoader;
5 4         9 our $VERSION = '1.0.2';
6 4         8113 XSLoader::load(__PACKAGE__, $VERSION);
7             }
8              
9 4     4   31 use strict;
  4         9  
  4         142  
10 4     4   21 use warnings;
  4         12  
  4         146  
11              
12 4     4   2607 use Couchbase::Client::Errors;
  4         22  
  4         479  
13 4     4   2013 use Couchbase::Client::IDXConst;
  4         9  
  4         824  
14 4     4   2059 use Couchbase::Client::Return;
  4         10  
  4         187  
15              
16 4     4   840854 my $have_storable = eval "use Storable; 1;";
  4         7836  
  4         179  
17 4     4   2118988 my $have_zlib = eval "use Compress::Zlib; 1;";
  4         5833794  
  4         1128  
18              
19 4     4   3227 use Array::Assign;
  4         3000  
  4         248  
20              
21             {
22 4     4   24 no warnings 'once';
  4         6  
  4         4233  
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__