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   2205 use utf8;
  1         2  
  1         5  
2 1     1   25 use strict;
  1         1  
  1         24  
3 1     1   3 use warnings;
  1         1  
  1         33  
4              
5             package DR::Tarantool::RealSyncClient;
6              
7              
8             =head1 NAME
9              
10             DR::Tarantool::RealSyncClient - a synchronous driver for L
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 but it doesn't
37             use L or L.
38              
39             The module uses L sockets.
40              
41             =head1 COPYRIGHT AND LICENSE
42              
43             Copyright (C) 2011 Dmitry E. Oboukhov
44             Copyright (C) 2011 Roman V. Nikolaev
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   270 use DR::Tarantool::LLSyncClient;
  1         2  
  1         36  
57 1     1   320 use DR::Tarantool::Spaces;
  1         1  
  1         26  
58 1     1   290 use DR::Tarantool::Tuple;
  1         1  
  1         24  
59 1     1   4 use Carp;
  1         1  
  1         52  
60             $Carp::Internal{ (__PACKAGE__) }++;
61 1     1   4 use Data::Dumper;
  1         1  
  1         33  
62 1     1   4 use Scalar::Util 'blessed';
  1         1  
  1         871  
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;