Skip to content

Commit 0f9b6d2

Browse files
committed
add support of a new binary protocol command for "call"
Added support for a new binary protocol command for "call" (used since tarantool 1.7.2). Unlike the old version, returned data is not converted to tuples (like in case of using "eval"). The set_modern_call_mode method was added to switch the "call" to modern mode and back. Closes #101
1 parent 6c098be commit 0f9b6d2

9 files changed

+138
-13
lines changed

README.md

+35-2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ Place it into project library path in your IDE.
8383
* [Tarantool::disconnect](#tarantooldisconnect)
8484
* [Tarantool::flushSchema](#tarantoolflushschema)
8585
* [Tarantool::ping](#tarantoolping)
86+
* [Tarantool::set_modern_call_mode](#tarantoolset_modern_call_mode)
8687
4. [Database queries](#database-queries)
8788
* [Tarantool::select](tarantool#select)
8889
* [Tarantool::insert, replace](#tarantoolinsert-tarantoolreplace)
@@ -122,6 +123,7 @@ Tarantool {
122123
public array Tarantool::select (mixed $space [, mixed $key = array() [, mixed $index = 0 [, int $limit = PHP_INT_MAX [, int $offset = 0 [, $iterator = Tarantool::ITERATOR_EQ ] ] ] ] ] )
123124
public array Tarantool::insert (mixed $space, array $tuple)
124125
public array Tarantool::replace (mixed $space, array $tuple)
126+
public bool Tarantool::set_modern_call_mode (bool enable_modern_mode)
125127
public array Tarantool::call (string $procedure [, mixed args] )
126128
public array Tarantool::evaluate (string $expression [, mixed args] )
127129
public array Tarantool::delete (mixed $space, mixed $key [, mixed $index] )
@@ -296,6 +298,31 @@ $tnt->insert("test", array(1, 3, "smth completely different"));
296298
$tnt->replace("test", array(1, 3, "smth completely different"));
297299
```
298300

301+
### Tarantool::set_modern_call_mode
302+
303+
``` php
304+
public bool Tarantool::set_modern_call_mode(bool $enable_modern_mode)
305+
```
306+
307+
_**Description**_: Switches "call" mode.
308+
If enable_modern_mode set to false the old mode of "call" will be used
309+
(returned data converted to tuples).
310+
If enable_modern_mode set to true the modern mode of "call" will be used
311+
(returned data is not converted to tuples). Since tarantool 1.7.2.
312+
313+
_**Parameters**_
314+
* `enable_modern_mode`: Bool, enable / disable modern mode (mandatory).
315+
316+
_**Return Value**_
317+
318+
**BOOL**: True.
319+
320+
#### Example
321+
322+
``` php
323+
$tnt->set_modern_call_mode(true);
324+
```
325+
299326
### Tarantool::call
300327

301328
``` php
@@ -306,14 +333,20 @@ _**Description**_: Call stored procedure
306333

307334
_**Parameters**_
308335
* `procedure`: String, procedure to call (mandatory)
309-
* `args`: Any value to pass to procdure as arguments (empty by default)
336+
* `args`: Any value to pass to procedure as arguments (empty by default)
310337

311338
_**Return Value**_
312339

340+
**BOOL**: False and raises `Exception` in case of error.
341+
342+
Modern mode disabled (default):
343+
313344
**Array of arrays** in case of success - tuples that were returned by stored
314345
procedure.
315346

316-
**BOOL**: False and raises `Exception` in case of error.
347+
Modern mode enabled:
348+
349+
**Any value**, that was returned by stored procedure.
317350

318351
#### Example
319352

src/php_tarantool.h

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <ext/standard/info.h>
1414
#include <ext/standard/base64.h>
1515

16+
#include <stdbool.h>
17+
1618
#ifdef HAVE_CONFIG_H
1719
# include "config.h"
1820
#endif
@@ -129,6 +131,7 @@ PHP_METHOD(Tarantool, ping);
129131
PHP_METHOD(Tarantool, select);
130132
PHP_METHOD(Tarantool, insert);
131133
PHP_METHOD(Tarantool, replace);
134+
PHP_METHOD(Tarantool, set_modern_call_mode);
132135
PHP_METHOD(Tarantool, call);
133136
PHP_METHOD(Tarantool, eval);
134137
PHP_METHOD(Tarantool, delete);
@@ -161,6 +164,12 @@ typedef struct tarantool_object {
161164
struct tp *tps;
162165
char *greeting;
163166
char *salt;
167+
/*
168+
* Enable the use "call" with EVAL-style marshalling,
169+
* i.e. returned data is not converted to tuples.
170+
* Since tarantool 1.7.2.
171+
*/
172+
bool modern_call_mode;
164173
/* Only for persistent connections */
165174
char *orig_login;
166175
char *suffix;

src/tarantool.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_tarantool_proc_tuple, 0, 0, 1)
549549
ZEND_ARG_INFO(0, tuple)
550550
ZEND_END_ARG_INFO()
551551

552+
/* set to use modern "call" mode (since 1.7.2) */
553+
ZEND_BEGIN_ARG_INFO_EX(arginfo_tarantool_call_mode, 0, 0, 1)
554+
ZEND_ARG_INFO(0, enable_modern_mode)
555+
ZEND_END_ARG_INFO()
556+
552557
ZEND_BEGIN_ARG_INFO_EX(arginfo_tarantool_update, 0, 0, 3)
553558
ZEND_ARG_INFO(0, space)
554559
ZEND_ARG_INFO(0, key)
@@ -575,6 +580,7 @@ const zend_function_entry Tarantool_methods[] = {
575580
TNT_MEP(select, arginfo_tarantool_select )
576581
TNT_MEP(insert, arginfo_tarantool_space_tuple )
577582
TNT_MEP(replace, arginfo_tarantool_space_tuple )
583+
TNT_MEP(set_modern_call_mode, arginfo_tarantool_call_mode )
578584
TNT_MEP(call, arginfo_tarantool_proc_tuple )
579585
TNT_MEP(eval, arginfo_tarantool_proc_tuple )
580586
TNT_MEP(delete, arginfo_tarantool_delete )
@@ -1166,6 +1172,10 @@ PHP_METHOD(Tarantool, __construct) {
11661172
}
11671173
zend_string_release(plist_id);
11681174
}
1175+
1176+
/* set default "call" mode */
1177+
obj->modern_call_mode = false;
1178+
11691179
t_obj->obj = obj;
11701180
t_obj->is_persistent = is_persistent;
11711181
return;
@@ -1467,7 +1477,13 @@ PHP_METHOD(Tarantool, call) {
14671477
pack_key(tuple, 1, &tuple_new);
14681478

14691479
long sync = TARANTOOL_G(sync_counter)++;
1470-
php_tp_encode_call(obj->value, sync, proc, proc_len, &tuple_new);
1480+
if (obj->modern_call_mode) {
1481+
php_tp_encode_call(obj->value, sync, proc, proc_len,
1482+
&tuple_new);
1483+
} else {
1484+
php_tp_encode_call_16(obj->value, sync, proc, proc_len,
1485+
&tuple_new);
1486+
}
14711487
zval_ptr_dtor(&tuple_new);
14721488
if (tarantool_stream_send(obj) == FAILURE)
14731489
RETURN_FALSE;
@@ -1479,6 +1495,14 @@ PHP_METHOD(Tarantool, call) {
14791495
TARANTOOL_RETURN_DATA(&body, &header, &body);
14801496
}
14811497

1498+
PHP_METHOD(Tarantool, set_modern_call_mode) {
1499+
bool enable_modern_mode;
1500+
TARANTOOL_FUNCTION_BEGIN(obj, id, "b", &enable_modern_mode);
1501+
obj->modern_call_mode = enable_modern_mode;
1502+
1503+
RETURN_TRUE;
1504+
}
1505+
14821506
PHP_METHOD(Tarantool, eval) {
14831507
char *code; size_t code_len;
14841508
zval *tuple = NULL, tuple_new;

src/tarantool_proto.c

+18-8
Original file line numberDiff line numberDiff line change
@@ -172,29 +172,39 @@ void php_tp_encode_delete(smart_string *str, uint32_t sync,
172172
php_mp_pack(str, tuple);
173173
}
174174

175-
size_t php_tp_sizeof_call(uint32_t sync,
176-
uint32_t proc_len, zval *tuple) {
177-
return php_tp_sizeof_header(TNT_CALL, sync) +
175+
static size_t php_tp_sizeof_call(uint32_t sync, uint32_t proc_len,
176+
enum tnt_request_type type, zval *tuple) {
177+
return php_tp_sizeof_header(type, sync) +
178178
php_mp_sizeof_hash(2) +
179179
php_mp_sizeof_long(TNT_FUNCTION) +
180180
php_mp_sizeof_string(proc_len) +
181181
php_mp_sizeof_long(TNT_TUPLE) +
182182
php_mp_sizeof(tuple) ;
183183
}
184184

185-
void php_tp_encode_call(smart_string *str, uint32_t sync,
186-
char *proc, uint32_t proc_len, zval *tuple) {
187-
size_t packet_size = php_tp_sizeof_call(sync,
188-
proc_len, tuple);
185+
static void php_tp_encode_call_common(smart_string *str, uint32_t sync,
186+
char *proc, uint32_t proc_len,
187+
enum tnt_request_type type, zval *tuple) {
188+
size_t packet_size = php_tp_sizeof_call(sync, proc_len, type, tuple);
189189
smart_string_ensure(str, packet_size + 5);
190-
php_tp_pack_header(str, packet_size, TNT_CALL, sync);
190+
php_tp_pack_header(str, packet_size, type, sync);
191191
php_mp_pack_hash(str, 2);
192192
php_mp_pack_long(str, TNT_FUNCTION);
193193
php_mp_pack_string(str, proc, proc_len);
194194
php_mp_pack_long(str, TNT_TUPLE);
195195
php_mp_pack(str, tuple);
196196
}
197197

198+
void php_tp_encode_call(smart_string *str, uint32_t sync, char *proc,
199+
uint32_t proc_len, zval *tuple) {
200+
php_tp_encode_call_common(str,sync, proc, proc_len, TNT_CALL, tuple);
201+
}
202+
203+
void php_tp_encode_call_16(smart_string *str, uint32_t sync, char *proc,
204+
uint32_t proc_len, zval *tuple) {
205+
php_tp_encode_call_common(str,sync, proc, proc_len, TNT_CALL_16, tuple);
206+
}
207+
198208
size_t php_tp_sizeof_eval(uint32_t sync,
199209
uint32_t proc_len, zval *tuple) {
200210
return php_tp_sizeof_header(TNT_EVAL, sync) +

src/tarantool_proto.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,11 @@ enum tnt_request_type {
8585
TNT_REPLACE = 0x03,
8686
TNT_UPDATE = 0x04,
8787
TNT_DELETE = 0x05,
88-
TNT_CALL = 0x06,
88+
TNT_CALL_16 = 0x06,
8989
TNT_AUTH = 0x07,
9090
TNT_EVAL = 0x08,
9191
TNT_UPSERT = 0x09,
92+
TNT_CALL = 0x0a,
9293
TNT_PING = 0x40
9394
};
9495

@@ -136,6 +137,8 @@ void php_tp_encode_delete(smart_string *str, uint32_t sync, uint32_t space_no,
136137
uint32_t index_no, zval *tuple);
137138
void php_tp_encode_call(smart_string *str, uint32_t sync, char *proc,
138139
uint32_t proc_len, zval *tuple);
140+
void php_tp_encode_call_16(smart_string *str, uint32_t sync, char *proc,
141+
uint32_t proc_len, zval *tuple);
139142
void php_tp_encode_eval(smart_string *str, uint32_t sync, char *proc,
140143
uint32_t proc_len, zval *tuple);
141144

test/DMLTest.php

+15
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ public function test_11_update_error() {
235235
}
236236

237237
public function test_12_call() {
238+
self::$tarantool->set_modern_call_mode(false);
238239
$result = self::$tarantool->call("test_6", array(true, false, false));
239240
$this->assertEquals(array(array(true), array(false), array(false)), $result);
240241
$this->assertEquals(
@@ -247,6 +248,20 @@ public function test_12_call() {
247248
);
248249
$this->assertEquals(
249250
self::$tarantool->call("test_3", array(3, 4)), array('0' => array('0' => 7)));
251+
252+
$check_call_17 = self::$tarantool->call('tarantool_version_at_least',
253+
array(1,7,2,0));
254+
if ($check_call_17) {
255+
self::$tarantool->set_modern_call_mode(true);
256+
$result = self::$tarantool->call("test_6", array(true, false, false));
257+
$this->assertEquals(array(true, false, false), $result);
258+
$this->assertEquals(
259+
array('0' => array('k1' => 'v2', 'k2' => 'v')),
260+
self::$tarantool->call("test_2")
261+
);
262+
$this->assertEquals(
263+
self::$tarantool->call("test_3", array(3, 4)), array('0' => 7));
264+
}
250265
}
251266

252267
public function test_13_eval() {

test/MsgPackTest.php

+20
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public static function doSetUpBeforeClass()
1818
}
1919

2020
public function test_00_msgpack_call() {
21+
self::$tarantool->set_modern_call_mode(false);
2122
$resp = self::$tarantool->call('test_4', [
2223
'4TL2tLIXqMqyGQm_kiE7mRrS96I5E8nqU', 'B627', 0, [
2324
'browser_stats_first_session_hits' => 1
@@ -30,6 +31,24 @@ public function test_00_msgpack_call() {
3031
]
3132
]);
3233
$this->assertEquals($resp[0][0], 2);
34+
35+
$check_call_17 = self::$tarantool->call('tarantool_version_at_least',
36+
array(1,7,2,0));
37+
if ($check_call_17) {
38+
self::$tarantool->set_modern_call_mode(true);
39+
$resp = self::$tarantool->call('test_4', [
40+
'4TL2tLIXqMqyGQm_kiE7mRrS96I5E8nqU', 'B627', 0, [
41+
'browser_stats_first_session_hits' => 1
42+
]
43+
]);
44+
$this->assertEquals($resp[0], 2);
45+
$resp = self::$tarantool->call('test_4', [
46+
'4TL2tLIXqMqyGQm_kiE7mRrS96I5E8nqU', 'B627', 0, [
47+
'browser_stats_first_session_hit' => 1
48+
]
49+
]);
50+
$this->assertEquals($resp[0], 2);
51+
}
3352
}
3453

3554
public function test_01_msgpack_array_key() {
@@ -81,6 +100,7 @@ public function test_05_msgpack_string_keys() {
81100
public function test_06_msgpack_array_reference() {
82101
$data = array('key1' => 'value1');
83102
$link = &$data['key1'];
103+
self::$tarantool->set_modern_call_mode(false);
84104
self::$tarantool->call('test_4', [$data]);
85105
}
86106
}

test/RandomTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,21 @@ public function test_02_very_big_response() {
4141
}
4242

4343
public function test_03_another_big_response() {
44+
self::$tarantool->set_modern_call_mode(false);
4445
for ($i = 100; $i <= 5200; $i += 100) {
4546
$result = self::$tarantool->call('test_5', array($i));
4647
$this->assertEquals($i, count($result));
4748
}
49+
50+
$check_call_17 = self::$tarantool->call('tarantool_version_at_least',
51+
array(1,7,2,0));
52+
if ($check_call_17) {
53+
self::$tarantool->set_modern_call_mode(true);
54+
for ($i = 100; $i <= 5200; $i += 100) {
55+
$result = self::$tarantool->call('test_5', array($i));
56+
$this->assertEquals($i, count($result[0]));
57+
}
58+
}
4859
}
4960

5061
/**

test/shared/box.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ local _TARANTOOL_MINOR = parse_tarantool_version(2)
2222
local _TARANTOOL_PATCH = parse_tarantool_version(3)
2323
local _TARANTOOL_REV = parse_tarantool_version(4)
2424

25-
local function tarantool_version_at_least(major, minor, patch, rev)
25+
function tarantool_version_at_least(major, minor, patch, rev)
2626
if _TARANTOOL_MAJOR < major then return false end
2727
if _TARANTOOL_MAJOR > major then return true end
2828

0 commit comments

Comments
 (0)