Skip to content

Commit fb8738c

Browse files
api: any msgpack supported type as a request key
Inserting a tuple with connector does not have any type restrictions on its contents: any MessagePack supported type is allowed. If there are any type violations on the Tarantool side, server would return the corresponding error. There is no reason to do any explicit type checks for request keys. This patch fixed using extended types as keys. Tarantool 2.10 does not support indexing intervals, so there are no tests for INTERVAL extension type. Closes #240
1 parent f5728c1 commit fb8738c

File tree

6 files changed

+58
-21
lines changed

6 files changed

+58
-21
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
145145

146146
### Fixed
147147
- Package build (#238).
148+
- Allow any MessagePack supported type as request key (#240).
148149

149150
## 0.9.0 - 2022-06-20
150151

tarantool/connection.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@
7878
)
7979
from tarantool.schema import Schema
8080
from tarantool.utils import (
81-
check_key,
8281
greeting_decode,
8382
version_id,
83+
wrap_key,
8484
ENCODING_DEFAULT,
8585
)
8686

@@ -1202,7 +1202,7 @@ def delete(self, space_name, key, *, index=0):
12021202
.. _delete: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/delete/
12031203
"""
12041204

1205-
key = check_key(key)
1205+
key = wrap_key(key)
12061206
if isinstance(space_name, str):
12071207
space_name = self.schema.get_space(space_name).sid
12081208
if isinstance(index, str):
@@ -1331,7 +1331,7 @@ def update(self, space_name, key, op_list, *, index=0):
13311331
.. _update: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/
13321332
"""
13331333

1334-
key = check_key(key)
1334+
key = wrap_key(key)
13351335
if isinstance(space_name, str):
13361336
space_name = self.schema.get_space(space_name).sid
13371337
if isinstance(index, str):
@@ -1516,7 +1516,7 @@ def select(self, space_name, key=None, *, offset=0, limit=0xffffffff, index=0, i
15161516

15171517
# Perform smart type checking (scalar / list of scalars / list of
15181518
# tuples)
1519-
key = check_key(key, select=True)
1519+
key = wrap_key(key, select=True)
15201520

15211521
if isinstance(space_name, str):
15221522
space_name = self.schema.get_space(space_name).sid

tarantool/utils.py

+12-17
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import sys
22
import uuid
33

4-
supported_types = (int, str, bytes, float,)
5-
64
ENCODING_DEFAULT = "utf-8"
75

86
from base64 import decodebytes as base64_decode
@@ -22,33 +20,30 @@ def strxor(rhs, lhs):
2220

2321
return bytes([x ^ y for x, y in zip(rhs, lhs)])
2422

25-
def check_key(*args, **kwargs):
23+
def wrap_key(*args, first=True, select=False):
2624
"""
27-
Validate request key types and map.
25+
Wrap request key in list, if needed.
2826
2927
:param args: Method args.
3028
:type args: :obj:`tuple`
3129
32-
:param kwargs: Method kwargs.
33-
:type kwargs: :obj:`dict`
30+
:param first: ``True`` if this is the first recursion iteration.
31+
:type first: :obj:`bool`
32+
33+
:param select: ``True`` if wrapping SELECT request key.
34+
:type select: :obj:`bool`
3435
3536
:rtype: :obj:`list`
3637
"""
3738

38-
if 'first' not in kwargs:
39-
kwargs['first'] = True
40-
if 'select' not in kwargs:
41-
kwargs['select'] = False
42-
if len(args) == 0 and kwargs['select']:
39+
if len(args) == 0 and select:
4340
return []
4441
if len(args) == 1:
45-
if isinstance(args[0], (list, tuple)) and kwargs['first']:
46-
kwargs['first'] = False
47-
return check_key(*args[0], **kwargs)
48-
elif args[0] is None and kwargs['select']:
42+
if isinstance(args[0], (list, tuple)) and first:
43+
return wrap_key(*args[0], first=False, select=select)
44+
elif args[0] is None and select:
4945
return []
50-
for key in args:
51-
assert isinstance(key, supported_types)
46+
5247
return list(args)
5348

5449

test/suites/test_datetime.py

+13
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ def setUpClass(self):
3232
parts = {1, 'string'},
3333
unique = true})
3434
35+
box.schema.space.create('test_pk')
36+
box.space['test_pk']:create_index('primary', {
37+
type = 'tree',
38+
parts = {1, 'datetime'},
39+
unique = true})
40+
3541
box.schema.user.create('test', {password = 'test', if_not_exists = true})
3642
box.schema.user.grant('test', 'read,write,execute', 'universe')
3743
@@ -528,6 +534,13 @@ def test_tarantool_datetime_addition_winter_time_switch(self):
528534
[case['res']])
529535

530536

537+
@skip_or_run_datetime_test
538+
def test_primary_key(self):
539+
data = [tarantool.Datetime(year=1970, month=1, day=1), 'content']
540+
541+
self.assertSequenceEqual(self.con.insert('test_pk', data), [data])
542+
self.assertSequenceEqual(self.con.select('test_pk', data[0]), [data])
543+
531544
@classmethod
532545
def tearDownClass(self):
533546
self.con.close()

test/suites/test_decimal.py

+14
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ def setUpClass(self):
3131
parts = {1, 'string'},
3232
unique = true})
3333
34+
box.schema.space.create('test_pk')
35+
box.space['test_pk']:create_index('primary', {
36+
type = 'tree',
37+
parts = {1, 'decimal'},
38+
unique = true})
39+
3440
box.schema.user.create('test', {password = 'test', if_not_exists = true})
3541
box.schema.user.grant('test', 'read,write,execute', 'universe')
3642
""")
@@ -421,6 +427,14 @@ def test_tarantool_encode_with_precision_loss(self):
421427
self.assertSequenceEqual(self.con.eval(lua_eval), [True])
422428

423429

430+
@skip_or_run_decimal_test
431+
def test_primary_key(self):
432+
data = [decimal.Decimal('0'), 'content']
433+
434+
self.assertSequenceEqual(self.con.insert('test_pk', data), [data])
435+
self.assertSequenceEqual(self.con.select('test_pk', data[0]), [data])
436+
437+
424438
@classmethod
425439
def tearDownClass(self):
426440
self.con.close()

test/suites/test_uuid.py

+14
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ def setUpClass(self):
3131
parts = {1, 'string'},
3232
unique = true})
3333
34+
box.schema.space.create('test_pk')
35+
box.space['test_pk']:create_index('primary', {
36+
type = 'tree',
37+
parts = {1, 'uuid'},
38+
unique = true})
39+
3440
box.schema.user.create('test', {password = 'test', if_not_exists = true})
3541
box.schema.user.grant('test', 'read,write,execute', 'universe')
3642
""")
@@ -125,6 +131,14 @@ def test_tarantool_encode(self):
125131
self.assertSequenceEqual(self.con.eval(lua_eval), [True])
126132

127133

134+
@skip_or_run_UUID_test
135+
def test_primary_key(self):
136+
data = [uuid.UUID('ae28d4f6-076c-49dd-8227-7f9fae9592d0'), 'content']
137+
138+
self.assertSequenceEqual(self.con.insert('test_pk', data), [data])
139+
self.assertSequenceEqual(self.con.select('test_pk', data[0]), [data])
140+
141+
128142
@classmethod
129143
def tearDownClass(self):
130144
self.con.close()

0 commit comments

Comments
 (0)