From dc287a792d9951b513a22e1fc57b0ba5a65701a7 Mon Sep 17 00:00:00 2001 From: igorcoding Date: Fri, 17 Feb 2017 02:50:15 +0300 Subject: [PATCH] Added ability to pass either list or tuple as params --- README.md | 1 + asynctnt/__init__.py | 2 +- asynctnt/connection.py | 7 ------- asynctnt/exceptions.py | 1 - asynctnt/iproto/buffer.pxd | 15 ++++++++------- asynctnt/iproto/buffer.pyx | 38 +++++++++++++++++++++++++------------- asynctnt/iproto/db.pxd | 16 ++++++++-------- asynctnt/iproto/db.pyx | 16 ++++++++-------- tests/test_op_call.py | 18 ++++++++++++------ tests/test_op_delete.py | 14 ++++++++------ tests/test_op_eval.py | 9 ++++++--- tests/test_op_select.py | 16 ++++++++++------ 12 files changed, 87 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 00fe01b..4c97f02 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # asynctnt [![Build Status](https://travis-ci.org/igorcoding/asynctnt.svg?branch=master)](https://travis-ci.org/igorcoding/asynctnt) +[![PyPI](https://img.shields.io/pypi/v/asynctnt.svg)](https://pypi.python.org/pypi/asynctnt) asynctnt is a high-performance [Tarantool](https://tarantool.org/) database diff --git a/asynctnt/__init__.py b/asynctnt/__init__.py index 354fc4e..32c92b3 100644 --- a/asynctnt/__init__.py +++ b/asynctnt/__init__.py @@ -1,4 +1,4 @@ from .connection import Connection, connect from .iproto.protocol import Iterator, Response -__version__ = '0.0.10' +__version__ = '0.0.11' diff --git a/asynctnt/connection.py b/asynctnt/connection.py index 925c4e0..8423102 100644 --- a/asynctnt/connection.py +++ b/asynctnt/connection.py @@ -457,13 +457,6 @@ def schema_id(self): return None return self._protocol.schema_id - @property - def encoding(self): - """ - Connection encoding - """ - return self._encoding - @property def initial_read_buffer_size(self): """ diff --git a/asynctnt/exceptions.py b/asynctnt/exceptions.py index d82bb9a..d35ce6c 100644 --- a/asynctnt/exceptions.py +++ b/asynctnt/exceptions.py @@ -14,7 +14,6 @@ class TarantoolDatabaseError(TarantoolError): def __init__(self, code, message): super(TarantoolDatabaseError, self).__init__(code, message) self.code = code - self.error_code = ErrorCode(code) self.message = message diff --git a/asynctnt/iproto/buffer.pxd b/asynctnt/iproto/buffer.pxd index 6f56043..6a8da82 100644 --- a/asynctnt/iproto/buffer.pxd +++ b/asynctnt/iproto/buffer.pxd @@ -50,26 +50,27 @@ cdef class WriteBuffer: cdef char *_encode_list(self, char *p, list arr) except NULL cdef char *_encode_tuple(self, char *p, tuple t) except NULL cdef char *_encode_dict(self, char *p, dict d) except NULL + cdef char *_encode_key_sequence(self, char *p, t) except NULL cdef char *_encode_obj(self, char *p, object o) except NULL cdef tnt.tnt_update_op_kind _op_type_to_kind(self, char *str, ssize_t len) cdef char *_encode_update_ops(self, char *p, list operations) except NULL - cdef void encode_request_call(self, str func_name, list args) except * - cdef void encode_request_eval(self, str expression, list args) except * + cdef void encode_request_call(self, str func_name, args) except * + cdef void encode_request_eval(self, str expression, args) except * cdef void encode_request_select(self, uint32_t space, uint32_t index, - list key, uint64_t offset, uint64_t limit, + key, uint64_t offset, uint64_t limit, uint32_t iterator) except * - cdef void encode_request_insert(self, uint32_t space, list t) except * + cdef void encode_request_insert(self, uint32_t space, t) except * cdef void encode_request_delete(self, uint32_t space, uint32_t index, - list key) except * + key) except * cdef void encode_request_update(self, uint32_t space, uint32_t index, - list key_tuple, list operations, + key_tuple, list operations, uint32_t key_of_tuple=*, uint32_t key_of_operations=* ) except * cdef void encode_request_upsert(self, uint32_t space, - list t, list operations) except * + t, list operations) except * cdef void encode_request_auth(self, bytes username, bytes scramble) except * diff --git a/asynctnt/iproto/buffer.pyx b/asynctnt/iproto/buffer.pyx index c4b3650..23f4963 100644 --- a/asynctnt/iproto/buffer.pyx +++ b/asynctnt/iproto/buffer.pyx @@ -295,6 +295,18 @@ cdef class WriteBuffer: return p + + cdef char *_encode_key_sequence(self, char *p, t) except NULL: + if isinstance(t, list) or t is None: + return self._encode_list(p, t) + elif isinstance(t, tuple): + return self._encode_tuple(p, t) + else: + raise TypeError( + 'sequence must be either list or tuple, ' + 'got: {}'.format(type(t)) + ) + cdef char *_encode_obj(self, char *p, object o) except NULL: cdef: bytes o_string_temp @@ -499,7 +511,7 @@ cdef class WriteBuffer: 'Unknown update operation type `{}`'.format(op_type_str)) return p - cdef void encode_request_call(self, str func_name, list args) except *: + cdef void encode_request_call(self, str func_name, args) except *: cdef: char *begin char *p @@ -537,9 +549,9 @@ cdef class WriteBuffer: p = mp_encode_uint(p, tnt.TP_TUPLE) self._length += (p - begin) - p = self._encode_list(p, args) + p = self._encode_key_sequence(p, args) - cdef void encode_request_eval(self, str expression, list args) except *: + cdef void encode_request_eval(self, str expression, args) except *: cdef: char *begin char *p @@ -577,10 +589,10 @@ cdef class WriteBuffer: p = mp_encode_uint(p, tnt.TP_TUPLE) self._length += (p - begin) - p = self._encode_list(p, args) + p = self._encode_key_sequence(p, args) cdef void encode_request_select(self, uint32_t space, uint32_t index, - list key, uint64_t offset, uint64_t limit, + key, uint64_t offset, uint64_t limit, uint32_t iterator) except *: cdef: char *begin @@ -637,9 +649,9 @@ cdef class WriteBuffer: p = mp_encode_uint(p, tnt.TP_KEY) self._length += (p - begin) - p = self._encode_list(p, key) + p = self._encode_key_sequence(p, key) - cdef void encode_request_insert(self, uint32_t space, list t) except *: + cdef void encode_request_insert(self, uint32_t space, t) except *: cdef: char *begin char *p @@ -666,10 +678,10 @@ cdef class WriteBuffer: p = mp_encode_uint(p, tnt.TP_TUPLE) self._length += (p - begin) - p = self._encode_list(p, t) + p = self._encode_key_sequence(p, t) cdef void encode_request_delete(self, uint32_t space, uint32_t index, - list key) except *: + key) except *: cdef: char *p uint32_t body_map_sz @@ -704,10 +716,10 @@ cdef class WriteBuffer: p = mp_encode_uint(p, tnt.TP_KEY) self._length += (p - begin) - p = self._encode_list(p, key) + p = self._encode_key_sequence(p, key) cdef void encode_request_update(self, uint32_t space, uint32_t index, - list key_tuple, list operations, + key_tuple, list operations, uint32_t key_of_tuple=tnt.TP_KEY, uint32_t key_of_operations=tnt.TP_TUPLE ) except *: @@ -747,13 +759,13 @@ cdef class WriteBuffer: self._length += (p - begin) p = self._encode_uint(p, key_of_tuple) - p = self._encode_list(p, key_tuple) + p = self._encode_key_sequence(p, key_tuple) p = self._encode_uint(p, key_of_operations) p = self._encode_update_ops(p, operations) cdef void encode_request_upsert(self, uint32_t space, - list t, list operations) except *: + t, list operations) except *: self.encode_request_update(space, 0, t, operations, tnt.TP_TUPLE, tnt.TP_OPERATIONS) diff --git a/asynctnt/iproto/db.pxd b/asynctnt/iproto/db.pxd index 8a35b37..285d037 100644 --- a/asynctnt/iproto/db.pxd +++ b/asynctnt/iproto/db.pxd @@ -14,16 +14,16 @@ cdef class Db: # cdef execute(self, Request req, float timeout) cdef Request _ping(self) - cdef Request _call16(self, str func_name, list args) - cdef Request _call(self, str func_name, list args) - cdef Request _eval(self, str expression, list args) - cdef Request _select(self, uint32_t space, uint32_t index, list key, + cdef Request _call16(self, str func_name, args) + cdef Request _call(self, str func_name, args) + cdef Request _eval(self, str expression, args) + cdef Request _select(self, uint32_t space, uint32_t index, key, uint64_t offset, uint64_t limit, uint32_t iterator) - cdef Request _insert(self, uint32_t space, list t, bint replace) - cdef Request _delete(self, uint32_t space, uint32_t index, list key) + cdef Request _insert(self, uint32_t space, t, bint replace) + cdef Request _delete(self, uint32_t space, uint32_t index, key) cdef Request _update(self, uint32_t space, uint32_t index, - list key, list operations) - cdef Request _upsert(self, uint32_t space, list t, list operations) + key, list operations) + cdef Request _upsert(self, uint32_t space, t, list operations) cdef Request _auth(self, bytes salt, str username, str password) @staticmethod diff --git a/asynctnt/iproto/db.pyx b/asynctnt/iproto/db.pyx index a8aa2bd..d4c17bc 100644 --- a/asynctnt/iproto/db.pyx +++ b/asynctnt/iproto/db.pyx @@ -51,7 +51,7 @@ cdef class Db: buf.write_length() return Request.new(op, sync, schema_id, buf) - cdef Request _call16(self, str func_name, list args): + cdef Request _call16(self, str func_name, args): cdef: tnt.tp_request_type op uint64_t sync @@ -67,7 +67,7 @@ cdef class Db: buf.write_length() return Request.new(op, sync, schema_id, buf) - cdef Request _call(self, str func_name, list args): + cdef Request _call(self, str func_name, args): cdef: tnt.tp_request_type op uint64_t sync @@ -83,7 +83,7 @@ cdef class Db: buf.write_length() return Request.new(op, sync, schema_id, buf) - cdef Request _eval(self, str expression, list args): + cdef Request _eval(self, str expression, args): cdef: tnt.tp_request_type op uint64_t sync @@ -99,7 +99,7 @@ cdef class Db: buf.write_length() return Request.new(op, sync, schema_id, buf) - cdef Request _select(self, uint32_t space, uint32_t index, list key, + cdef Request _select(self, uint32_t space, uint32_t index, key, uint64_t offset, uint64_t limit, uint32_t iterator): cdef: tnt.tp_request_type op @@ -117,7 +117,7 @@ cdef class Db: buf.write_length() return Request.new(op, sync, schema_id, buf) - cdef Request _insert(self, uint32_t space, list t, bint replace): + cdef Request _insert(self, uint32_t space, t, bint replace): cdef: tnt.tp_request_type op uint64_t sync @@ -133,7 +133,7 @@ cdef class Db: buf.write_length() return Request.new(op, sync, schema_id, buf) - cdef Request _delete(self, uint32_t space, uint32_t index, list key): + cdef Request _delete(self, uint32_t space, uint32_t index, key): cdef: tnt.tp_request_type op uint64_t sync @@ -150,7 +150,7 @@ cdef class Db: return Request.new(op, sync, schema_id, buf) cdef Request _update(self, uint32_t space, uint32_t index, - list key, list operations): + key, list operations): cdef: tnt.tp_request_type op uint64_t sync @@ -166,7 +166,7 @@ cdef class Db: buf.write_length() return Request.new(op, sync, schema_id, buf) - cdef Request _upsert(self, uint32_t space, list t, list operations): + cdef Request _upsert(self, uint32_t space, t, list operations): cdef: tnt.tp_request_type op uint64_t sync diff --git a/tests/test_op_call.py b/tests/test_op_call.py index bbd4303..841f858 100644 --- a/tests/test_op_call.py +++ b/tests/test_op_call.py @@ -70,15 +70,18 @@ async def test__call_params_invalid_type(self): with self.assertRaises(TypeError): await self.conn.call('func_param', 220349) - with self.assertRaises(TypeError): - await self.conn.call('func_param', (1, 2)) - with self.assertRaises(TypeError): await self.conn.call('func_param', 'hey') with self.assertRaises(TypeError): await self.conn.call('func_param', {1: 1, 2: 2}) + async def test__call_args_tuple(self): + try: + await self.conn.call('func_param', (1, 2)) + except Exception as e: + self.fail(e) + async def test__call_complex_param(self): p, cmp = get_complex_param(encoding=self.conn.encoding) res = await self.conn.call('func_param', [p]) @@ -158,15 +161,18 @@ async def test__call16_params_invalid_type(self): with self.assertRaises(TypeError): await self.conn.call16('func_param', 220349) - with self.assertRaises(TypeError): - await self.conn.call16('func_param', (1, 2)) - with self.assertRaises(TypeError): await self.conn.call16('func_param', 'hey') with self.assertRaises(TypeError): await self.conn.call16('func_param', {1: 1, 2: 2}) + async def test__call16_args_tuple(self): + try: + await self.conn.call16('func_param', (1, 2)) + except Exception as e: + self.fail(e) + async def test__call16_complex_param(self): p, cmp = get_complex_param(encoding=self.conn.encoding) res = await self.conn.call('func_param', [p]) diff --git a/tests/test_op_delete.py b/tests/test_op_delete.py index ade9f21..52cae34 100644 --- a/tests/test_op_delete.py +++ b/tests/test_op_delete.py @@ -109,14 +109,16 @@ async def test__delete_by_index_name_no_schema(self): async def test__delete_invalid_types(self): with self.assertRaisesRegex( - TypeError, "missing 2 required positional arguments: 'space' and 'key'"): + TypeError, + "missing 2 required positional arguments: 'space' and 'key'"): await self.conn.delete() with self.assertRaisesRegex( - TypeError, r'Expected list, got '): - await self.conn.delete(self.TESTER_SPACE_ID, (1,)) - - with self.assertRaisesRegex( - TypeError, r'Expected list, got '): + TypeError, r'sequence must be either list or tuple'): await self.conn.delete(self.TESTER_SPACE_ID, {}) + async def test__delete_key_tuple(self): + try: + await self.conn.delete(self.TESTER_SPACE_ID, (1,)) + except Exception as e: + self.fail(e) diff --git a/tests/test_op_eval.py b/tests/test_op_eval.py index a6c9dbf..784510d 100644 --- a/tests/test_op_eval.py +++ b/tests/test_op_eval.py @@ -52,15 +52,18 @@ async def test__eval_params_invalid_type(self): with self.assertRaises(TypeError): await self.conn.eval('return {...}', 220349) - with self.assertRaises(TypeError): - await self.conn.eval('return {...}', (1, 2)) - with self.assertRaises(TypeError): await self.conn.eval('return {...}', 'hey') with self.assertRaises(TypeError): await self.conn.eval('return {...}', {1: 1, 2: 2}) + async def test__eval_args_tuple(self): + try: + await self.conn.eval('return {...}', (1, 2)) + except Exception as e: + self.fail(e) + async def test__eval_complex_param(self): p, cmp = get_complex_param(encoding=self.conn.encoding) res = await self.conn.eval('return {...}', [p]) diff --git a/tests/test_op_select.py b/tests/test_op_select.py index 5aa2bd1..cb1fcb6 100644 --- a/tests/test_op_select.py +++ b/tests/test_op_select.py @@ -173,17 +173,21 @@ async def test__select_all_params(self): iterator=Iterator.LE) self.assertListEqual(res.body, list(reversed(data))[1:3], 'Body ok') + async def test__select_key_tuple(self): + try: + await self.conn.select(self.TESTER_SPACE_ID, (1,)) + except Exception as e: + self.fail(e) + async def test__select_invalid_types(self): with self.assertRaisesRegex( - TypeError, r'missing 1 required positional argument: \'space\''): + TypeError, + r'missing 1 required positional argument: \'space\''): await self.conn.select() with self.assertRaisesRegex( - TypeError, r'Expected list, got tuple'): - await self.conn.select(self.TESTER_SPACE_ID, (1,)) - - with self.assertRaisesRegex( - TypeError, r'Expected list, got int'): + TypeError, + r'sequence must be either list or tuple, got: '): await self.conn.select(self.TESTER_SPACE_ID, 1) with self.assertRaisesRegex(