File Coverage

blib/lib/DR/Tarantool/RealSyncClient.pm
Criterion Covered Total %
statement 27 100 27.0
branch 0 26 0.0
condition 0 22 0.0
subroutine 9 21 42.8
pod 0 11 0.0
total 36 180 20.0


line stmt bran cond sub pod time code
1 1     1   4214 use utf8;
  1         3  
  1         11  
2 1     1   34 use strict;
  1         2  
  1         39  
3 1     1   5 use warnings;
  1         3  
  1         64  
4              
5             package DR::Tarantool::RealSyncClient;
6              
7              
8             =head1 NAME
9              
10             DR::Tarantool::RealSyncClient - a synchronous driver for L<Tarantool/Box|http://tarantool.org>
11              
12             =head1 SYNOPSIS
13              
14             my $client = DR::Tarantool::RealSyncClient->connect(
15             port => $tnt->primary_port,
16             spaces => $spaces
17             );
18              
19             if ($client->ping) { .. };
20              
21             my $t = $client->insert(
22             first_space => [ 1, 'val', 2, 'test' ], TNT_FLAG_RETURN
23             );
24              
25             $t = $client->call_lua('luafunc' => [ 0, 0, 1 ], 'space_name');
26              
27             $t = $client->select(space_name => $key);
28              
29             $t = $client->update(space_name => 2 => [ name => set => 'new' ]);
30              
31             $client->delete(space_name => $key);
32              
33              
34             =head1 DESCRIPTION
35              
36             The module is a clone of L<DR::Tarantool::SyncClient> but it doesn't
37             use L<AnyEvent> or L<Coro>.
38              
39             The module uses L<IO::Socket> sockets.
40              
41             =head1 COPYRIGHT AND LICENSE
42              
43             Copyright (C) 2011 Dmitry E. Oboukhov <unera@debian.org>
44             Copyright (C) 2011 Roman V. Nikolaev <rshadow@rambler.ru>
45              
46             This program is free software, you can redistribute it and/or
47             modify it under the terms of the Artistic License.
48              
49             =head1 VCS
50              
51             The project is placed git repo on github:
52             L<|https://github.com/dr-co/dr-tarantool/>.
53              
54             =cut
55              
56 1     1   541 use DR::Tarantool::LLSyncClient;
  1         4  
  1         36  
57 1     1   625 use DR::Tarantool::Spaces;
  1         5  
  1         46  
58 1     1   596 use DR::Tarantool::Tuple;
  1         48  
  1         39  
59 1     1   7 use Carp;
  1         2  
  1         76  
60             $Carp::Internal{ (__PACKAGE__) }++;
61 1     1   5 use Data::Dumper;
  1         2  
  1         52  
62 1     1   6 use Scalar::Util 'blessed';
  1         3  
  1         1490  
63              
64             my $unpack = sub {
65             my ($self, $res, $s) = @_;
66             return undef unless $res and $res->{status} eq 'ok';
67             return $s->tuple_class->unpack( $res->{tuples}, $s ) if $s;
68             return $res->{tuples};
69             };
70              
71             sub connect {
72 0     0 0   my ($class, %opts) = @_;
73              
74 0   0       my $host = $opts{host} || 'localhost';
75 0 0         my $port = $opts{port} or croak "port isn't defined";
76              
77 0 0         my $spaces = blessed($opts{spaces}) ?
78             $opts{spaces} : DR::Tarantool::Spaces->new($opts{spaces});
79 0   0       my $reconnect_period = $opts{reconnect_period} || 0;
80 0   0       my $reconnect_always = $opts{reconnect_always} || 0;
81              
82 0 0         my $client = DR::Tarantool::LLSyncClient->connect(
    0          
83             host => $host,
84             port => $port,
85             reconnect_period => $reconnect_period,
86             reconnect_always => $reconnect_always,
87             exists($opts{raise_error}) ?
88             ( raise_error => $opts{raise_error} ? 1: 0 )
89             : (),
90             );
91              
92              
93 0 0         return undef unless $client;
94 0   0       return bless { llc => $client, spaces => $spaces } => ref($class) || $class;
95             }
96              
97             sub space {
98 0     0 0   my ($self, $name) = @_;
99 0           return $self->{spaces}->space($name);
100             }
101              
102              
103             sub ping {
104 0     0 0   my ($self) = @_;
105 0           $self->{llc}->ping;
106             }
107              
108             sub insert {
109 0     0 0   my $self = shift;
110 0           my $space = shift;
111 0           $self->_llc->_check_tuple( my $tuple = shift );
112 0   0       my $flags = pop || 0;
113              
114 0           my $s = $self->{spaces}->space($space);
115              
116 0           my $res =
117             $self->_llc->insert( $s->number, $s->pack_tuple( $tuple ), $flags );
118 0           return $unpack->($self, $res, $s);
119             }
120              
121             sub call_lua {
122 0     0 0   my $self = shift;
123 0           my $lua_name = shift;
124 0           my $args = shift;
125              
126 0 0         unshift @_ => 'space' if @_ == 1;
127 0           my %opts = @_;
128              
129 0   0       my $flags = $opts{flags} || 0;
130 0           my $space_name = $opts{space};
131 0           my $fields = $opts{fields};
132              
133 0           my $s;
134 0 0 0       croak "You can't use 'fields' and 'space' at the same time"
135             if $fields and $space_name;
136              
137 0 0         if ($space_name) {
    0          
138 0           $s = $self->space( $space_name );
139             } elsif ( $fields ) {
140 0           $s = DR::Tarantool::Space->new(
141             0 =>
142             {
143             name => 'temp_space',
144             fields => $fields,
145             indexes => {}
146             },
147             );
148             } else {
149 0           $s = DR::Tarantool::Space->new(
150             0 =>
151             {
152             name => 'temp_space',
153             fields => [],
154             indexes => {}
155             },
156             );
157             }
158              
159 0 0         if ($opts{args}) {
160 0           my $sa = DR::Tarantool::Space->new(
161             0 =>
162             {
163             name => 'temp_space_args',
164             fields => $opts{args},
165             indexes => {}
166             },
167             );
168 0           $args = $sa->pack_tuple( $args );
169             }
170              
171 0           my $res = $self->_llc->call_lua( $lua_name, $args, $flags );
172              
173 0           return $unpack->($self, $res, $s);
174             }
175              
176              
177             sub select {
178 0     0 0   my $self = shift;
179 0           my $space = shift;
180 0           my $keys = shift;
181              
182 0           my ($index, $limit, $offset);
183              
184 0 0         if (@_ == 1) {
    0          
    0          
185 0           $index = shift;
186             } elsif (@_ == 3) {
187 0           ($index, $limit, $offset) = @_;
188             } elsif (@_) {
189 0           my %opts = @_;
190 0           $index = $opts{index};
191 0           $limit = $opts{limit};
192 0           $offset = $opts{offset};
193             }
194              
195 0   0       $index ||= 0;
196              
197 0           my $s = $self->space($space);
198              
199 0           my $res = $self->_llc->select(
200             $s->number,
201             $s->_index( $index )->{no},
202             $s->pack_keys( $keys, $index ),
203             $limit,
204             $offset
205             );
206              
207 0           return $unpack->($self, $res, $s);
208             }
209              
210             sub update {
211 0     0 0   my $self = shift;
212 0           my $space = shift;
213 0           my $key = shift;
214 0           my $op = shift;
215 0   0       my $flags = shift || 0;
216              
217 0           my $s = $self->space($space);
218              
219 0           my $res = $self->_llc->update(
220             $s->number,
221             $s->pack_primary_key( $key ),
222             $s->pack_operations( $op ),
223             $flags,
224             );
225 0           return $unpack->($self, $res, $s);
226             }
227              
228             sub delete :method {
229 0     0 0   my $self = shift;
230 0           my $space = shift;
231 0           my $key = shift;
232 0   0       my $flags = shift || 0;
233              
234 0           my $s = $self->space($space);
235              
236 0           my $res = $self->_llc->delete(
237             $s->number,
238             $s->pack_primary_key( $key ),
239             $flags,
240             );
241 0           return $unpack->($self, $res, $s);
242             }
243              
244 0     0 0   sub last_code { $_[0]->{llc}->last_code }
245 0     0 0   sub last_error_string { $_[0]->{llc}->last_error_string }
246 0     0 0   sub raise_error { $_[0]->raise_error };
247 0     0     sub _llc { $_[0]{llc} }
248              
249             1;