Skip to content

Commit

Permalink
add support of a new binary protocol command for "call"
Browse files Browse the repository at this point in the history
* 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 use_17_call method was added to switch the "call" to call_17
  mode and back.

Closes #101
  • Loading branch information
LeonidVas committed Jul 17, 2020
1 parent 6c098be commit e5d21cd
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 12 deletions.
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Place it into project library path in your IDE.
* [Tarantool::disconnect](#tarantooldisconnect)
* [Tarantool::flushSchema](#tarantoolflushschema)
* [Tarantool::ping](#tarantoolping)
* [Tarantool::use_call_17](#tarantooluse_17_call)
4. [Database queries](#database-queries)
* [Tarantool::select](tarantool#select)
* [Tarantool::insert, replace](#tarantoolinsert-tarantoolreplace)
Expand Down Expand Up @@ -122,6 +123,7 @@ Tarantool {
public array Tarantool::select (mixed $space [, mixed $key = array() [, mixed $index = 0 [, int $limit = PHP_INT_MAX [, int $offset = 0 [, $iterator = Tarantool::ITERATOR_EQ ] ] ] ] ] )
public array Tarantool::insert (mixed $space, array $tuple)
public array Tarantool::replace (mixed $space, array $tuple)
public bool Tarantool::use_17_call (bool enable)
public array Tarantool::call (string $procedure [, mixed args] )
public array Tarantool::evaluate (string $expression [, mixed args] )
public array Tarantool::delete (mixed $space, mixed $key [, mixed $index] )
Expand Down Expand Up @@ -296,6 +298,32 @@ $tnt->insert("test", array(1, 3, "smth completely different"));
$tnt->replace("test", array(1, 3, "smth completely different"));
```

### Tarantool::use_17_call

``` php
public bool Tarantool::use_17_call(bool $enable)
```

_**Description**_: Switches "call" mode.
If enable set to false the call_16 mode of "call" will be used
(returned data converted to tuples).
If enable set to true the call_17 mode of "call" will be used
(returned data has an arbitrary structure). Since tarantool 1.7.2.
Default - call_16 mode.

_**Parameters**_
* `enable`: Bool, enable / disable call_17 mode (mandatory).

_**Return Value**_

**BOOL**: True.

#### Example

``` php
$tnt->use_17_call(true);
```

### Tarantool::call

``` php
Expand All @@ -306,14 +334,20 @@ _**Description**_: Call stored procedure

_**Parameters**_
* `procedure`: String, procedure to call (mandatory)
* `args`: Any value to pass to procdure as arguments (empty by default)
* `args`: Any value to pass to procedure as arguments (empty by default)

_**Return Value**_

**BOOL**: False and raises `Exception` in case of error.

call_16 mode (default):

**Array of arrays** in case of success - tuples that were returned by stored
procedure.

**BOOL**: False and raises `Exception` in case of error.
call_17 mode:

**Any value**, that was returned by stored procedure.

#### Example

Expand Down
9 changes: 9 additions & 0 deletions src/php_tarantool.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <ext/standard/info.h>
#include <ext/standard/base64.h>

#include <stdbool.h>

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
Expand Down Expand Up @@ -129,6 +131,7 @@ PHP_METHOD(Tarantool, ping);
PHP_METHOD(Tarantool, select);
PHP_METHOD(Tarantool, insert);
PHP_METHOD(Tarantool, replace);
PHP_METHOD(Tarantool, use_17_call);
PHP_METHOD(Tarantool, call);
PHP_METHOD(Tarantool, eval);
PHP_METHOD(Tarantool, delete);
Expand Down Expand Up @@ -161,6 +164,12 @@ typedef struct tarantool_object {
struct tp *tps;
char *greeting;
char *salt;
/*
* Enable the use "call" with EVAL-style marshalling,
* i.e. returned data is not converted to tuples.
* Since tarantool 1.7.2.
*/
bool call_17_enable;
/* Only for persistent connections */
char *orig_login;
char *suffix;
Expand Down
26 changes: 25 additions & 1 deletion src/tarantool.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_tarantool_proc_tuple, 0, 0, 1)
ZEND_ARG_INFO(0, tuple)
ZEND_END_ARG_INFO()

/* set to use call_17 "call" mode (since 1.7.2) */
ZEND_BEGIN_ARG_INFO_EX(arginfo_tarantool_call_mode, 0, 0, 1)
ZEND_ARG_INFO(0, enable)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_tarantool_update, 0, 0, 3)
ZEND_ARG_INFO(0, space)
ZEND_ARG_INFO(0, key)
Expand All @@ -575,6 +580,7 @@ const zend_function_entry Tarantool_methods[] = {
TNT_MEP(select, arginfo_tarantool_select )
TNT_MEP(insert, arginfo_tarantool_space_tuple )
TNT_MEP(replace, arginfo_tarantool_space_tuple )
TNT_MEP(use_17_call, arginfo_tarantool_call_mode )
TNT_MEP(call, arginfo_tarantool_proc_tuple )
TNT_MEP(eval, arginfo_tarantool_proc_tuple )
TNT_MEP(delete, arginfo_tarantool_delete )
Expand Down Expand Up @@ -1166,6 +1172,10 @@ PHP_METHOD(Tarantool, __construct) {
}
zend_string_release(plist_id);
}

/* set default "call" mode */
obj->call_17_enable = false;

t_obj->obj = obj;
t_obj->is_persistent = is_persistent;
return;
Expand Down Expand Up @@ -1467,7 +1477,13 @@ PHP_METHOD(Tarantool, call) {
pack_key(tuple, 1, &tuple_new);

long sync = TARANTOOL_G(sync_counter)++;
php_tp_encode_call(obj->value, sync, proc, proc_len, &tuple_new);
if (obj->call_17_enable) {
php_tp_encode_call(obj->value, sync, proc, proc_len,
&tuple_new);
} else {
php_tp_encode_call_16(obj->value, sync, proc, proc_len,
&tuple_new);
}
zval_ptr_dtor(&tuple_new);
if (tarantool_stream_send(obj) == FAILURE)
RETURN_FALSE;
Expand All @@ -1479,6 +1495,14 @@ PHP_METHOD(Tarantool, call) {
TARANTOOL_RETURN_DATA(&body, &header, &body);
}

PHP_METHOD(Tarantool, use_17_call) {
bool enable;
TARANTOOL_FUNCTION_BEGIN(obj, id, "b", &enable);
obj->call_17_enable = enable;

RETURN_TRUE;
}

PHP_METHOD(Tarantool, eval) {
char *code; size_t code_len;
zval *tuple = NULL, tuple_new;
Expand Down
26 changes: 18 additions & 8 deletions src/tarantool_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,29 +172,39 @@ void php_tp_encode_delete(smart_string *str, uint32_t sync,
php_mp_pack(str, tuple);
}

size_t php_tp_sizeof_call(uint32_t sync,
uint32_t proc_len, zval *tuple) {
return php_tp_sizeof_header(TNT_CALL, sync) +
static size_t php_tp_sizeof_call(uint32_t sync, uint32_t proc_len,
enum tnt_request_type type, zval *tuple) {
return php_tp_sizeof_header(type, sync) +
php_mp_sizeof_hash(2) +
php_mp_sizeof_long(TNT_FUNCTION) +
php_mp_sizeof_string(proc_len) +
php_mp_sizeof_long(TNT_TUPLE) +
php_mp_sizeof(tuple) ;
}

void php_tp_encode_call(smart_string *str, uint32_t sync,
char *proc, uint32_t proc_len, zval *tuple) {
size_t packet_size = php_tp_sizeof_call(sync,
proc_len, tuple);
static void php_tp_encode_call_impl(smart_string *str, uint32_t sync,
char *proc, uint32_t proc_len,
enum tnt_request_type type, zval *tuple) {
size_t packet_size = php_tp_sizeof_call(sync, proc_len, type, tuple);
smart_string_ensure(str, packet_size + 5);
php_tp_pack_header(str, packet_size, TNT_CALL, sync);
php_tp_pack_header(str, packet_size, type, sync);
php_mp_pack_hash(str, 2);
php_mp_pack_long(str, TNT_FUNCTION);
php_mp_pack_string(str, proc, proc_len);
php_mp_pack_long(str, TNT_TUPLE);
php_mp_pack(str, tuple);
}

void php_tp_encode_call(smart_string *str, uint32_t sync, char *proc,
uint32_t proc_len, zval *tuple) {
php_tp_encode_call_impl(str,sync, proc, proc_len, TNT_CALL, tuple);
}

void php_tp_encode_call_16(smart_string *str, uint32_t sync, char *proc,
uint32_t proc_len, zval *tuple) {
php_tp_encode_call_impl(str,sync, proc, proc_len, TNT_CALL_16, tuple);
}

size_t php_tp_sizeof_eval(uint32_t sync,
uint32_t proc_len, zval *tuple) {
return php_tp_sizeof_header(TNT_EVAL, sync) +
Expand Down
5 changes: 4 additions & 1 deletion src/tarantool_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ enum tnt_request_type {
TNT_REPLACE = 0x03,
TNT_UPDATE = 0x04,
TNT_DELETE = 0x05,
TNT_CALL = 0x06,
TNT_CALL_16 = 0x06,
TNT_AUTH = 0x07,
TNT_EVAL = 0x08,
TNT_UPSERT = 0x09,
TNT_CALL = 0x0a,
TNT_PING = 0x40
};

Expand Down Expand Up @@ -136,6 +137,8 @@ void php_tp_encode_delete(smart_string *str, uint32_t sync, uint32_t space_no,
uint32_t index_no, zval *tuple);
void php_tp_encode_call(smart_string *str, uint32_t sync, char *proc,
uint32_t proc_len, zval *tuple);
void php_tp_encode_call_16(smart_string *str, uint32_t sync, char *proc,
uint32_t proc_len, zval *tuple);
void php_tp_encode_eval(smart_string *str, uint32_t sync, char *proc,
uint32_t proc_len, zval *tuple);

Expand Down
15 changes: 15 additions & 0 deletions test/DMLTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ public function test_11_update_error() {
}

public function test_12_call() {
self::$tarantool->use_17_call(false);
$result = self::$tarantool->call("test_6", array(true, false, false));
$this->assertEquals(array(array(true), array(false), array(false)), $result);
$this->assertEquals(
Expand All @@ -247,6 +248,20 @@ public function test_12_call() {
);
$this->assertEquals(
self::$tarantool->call("test_3", array(3, 4)), array('0' => array('0' => 7)));

$check_call_17 = self::$tarantool->call('tarantool_version_at_least',
array(1,7,2,0));
if ($check_call_17[0][0]) {
self::$tarantool->use_17_call(true);
$result = self::$tarantool->call("test_6", array(true, false, false));
$this->assertEquals(array(true, false, false), $result);
$this->assertEquals(
array('0' => array('k1' => 'v2', 'k2' => 'v')),
self::$tarantool->call("test_2")
);
$this->assertEquals(
self::$tarantool->call("test_3", array(3, 4)), array('0' => 7));
}
}

public function test_13_eval() {
Expand Down
20 changes: 20 additions & 0 deletions test/MsgPackTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static function doSetUpBeforeClass()
}

public function test_00_msgpack_call() {
self::$tarantool->use_17_call(false);
$resp = self::$tarantool->call('test_4', [
'4TL2tLIXqMqyGQm_kiE7mRrS96I5E8nqU', 'B627', 0, [
'browser_stats_first_session_hits' => 1
Expand All @@ -30,6 +31,24 @@ public function test_00_msgpack_call() {
]
]);
$this->assertEquals($resp[0][0], 2);

$check_call_17 = self::$tarantool->call('tarantool_version_at_least',
array(1,7,2,0));
if ($check_call_17[0][0]) {
self::$tarantool->use_17_call(true);
$resp = self::$tarantool->call('test_4', [
'4TL2tLIXqMqyGQm_kiE7mRrS96I5E8nqU', 'B627', 0, [
'browser_stats_first_session_hits' => 1
]
]);
$this->assertEquals($resp[0], 2);
$resp = self::$tarantool->call('test_4', [
'4TL2tLIXqMqyGQm_kiE7mRrS96I5E8nqU', 'B627', 0, [
'browser_stats_first_session_hit' => 1
]
]);
$this->assertEquals($resp[0], 2);
}
}

public function test_01_msgpack_array_key() {
Expand Down Expand Up @@ -81,6 +100,7 @@ public function test_05_msgpack_string_keys() {
public function test_06_msgpack_array_reference() {
$data = array('key1' => 'value1');
$link = &$data['key1'];
self::$tarantool->use_17_call(false);
self::$tarantool->call('test_4', [$data]);
}
}
11 changes: 11 additions & 0 deletions test/RandomTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,21 @@ public function test_02_very_big_response() {
}

public function test_03_another_big_response() {
self::$tarantool->use_17_call(false);
for ($i = 100; $i <= 5200; $i += 100) {
$result = self::$tarantool->call('test_5', array($i));
$this->assertEquals($i, count($result));
}

$check_call_17 = self::$tarantool->call('tarantool_version_at_least',
array(1,7,2,0));
if ($check_call_17[0][0]) {
self::$tarantool->use_17_call(true);
for ($i = 100; $i <= 5200; $i += 100) {
$result = self::$tarantool->call('test_5', array($i));
$this->assertEquals($i, count($result[0]));
}
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions test/shared/box.lua
Original file line number Diff line number Diff line change
Expand Up @@ -180,5 +180,8 @@ function test_6(...)
return ...
end

-- export tarantool_version_at_least function
_G.tarantool_version_at_least = tarantool_version_at_least

require('console').listen(os.getenv('ADMIN_PORT'))

0 comments on commit e5d21cd

Please sign in to comment.