Skip to content

Commit 30b54ef

Browse files
committed
Add support for field names in update/upsert
closes gh-46
1 parent 737308c commit 30b54ef

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@
99
sophia
1010
*.egg-info
1111
.tox
12+
13+
*.xlog
14+
*.snap
15+
*.vylog

tarantool/connection.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
This module provides low-level API for Tarantool
55
'''
66

7+
import os
78
import six
9+
import copy
810
import time
911
import errno
1012
import ctypes
1113
import ctypes.util
1214
import socket
1315
import msgpack
14-
import os
1516

1617
try:
1718
from ctypes import c_ssize_t
@@ -429,6 +430,15 @@ class JoinState:
429430
if state == JoinState.Done:
430431
return
431432

433+
def _ops_process(self, space, update_ops):
434+
new_ops = []
435+
for op in update_ops:
436+
if isinstance(op[1], six.string_types):
437+
op = list(op)
438+
op[1] = self.schema.get_field(space, op[1])['id']
439+
new_ops.append(op)
440+
return new_ops
441+
432442
def join(self, server_uuid):
433443
self._opt_reconnect()
434444
if self.version_id < version_id(1, 7, 0):
@@ -555,6 +565,7 @@ def upsert(self, space_name, tuple_value, op_list, **kwargs):
555565
space_name = self.schema.get_space(space_name).sid
556566
if isinstance(index_name, six.string_types):
557567
index_name = self.schema.get_index(space_name, index_name).iid
568+
op_list = self._ops_process(space_name, op_list)
558569
request = RequestUpsert(self, space_name, index_name, tuple_value,
559570
op_list)
560571
return self._send_request(request)
@@ -629,6 +640,7 @@ def update(self, space_name, key, op_list, **kwargs):
629640
space_name = self.schema.get_space(space_name).sid
630641
if isinstance(index_name, six.string_types):
631642
index_name = self.schema.get_index(space_name, index_name).iid
643+
op_list = self._ops_process(space_name, op_list)
632644
request = RequestUpdate(self, space_name, index_name, key, op_list)
633645
return self._send_request(request)
634646

tarantool/schema.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ def __init__(self, space_row, schema):
5252
self.schema[self.sid] = self
5353
if self.name:
5454
self.schema[self.name] = self
55+
self.format = dict()
56+
for part_id, part in enumerate(space_row[6]):
57+
part['id'] = part_id
58+
self.format[part['name']] = part
59+
self.format[part_id ] = part
5560

5661
def flush(self):
5762
del self.schema[self.sid]
@@ -189,5 +194,18 @@ def fetch_index_from(self, space, index):
189194

190195
return index_row
191196

197+
def get_field(self, space, field):
198+
_space = self.get_space(space)
199+
try:
200+
return _space.format[field]
201+
except:
202+
tp = 'name' if isinstance(field, six.string_types) else 'id'
203+
errmsg = "There's no field with {2} '{0}' in space '{1}'".format(
204+
field, _space.name, tp
205+
)
206+
raise SchemaError(errmsg)
207+
208+
return field
209+
192210
def flush(self):
193211
self.schema.clear()

tests/suites/lib/tarantool_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def __exit__(self, type, value, tb):
8585
self.disconnect()
8686

8787
def __call__(self, command):
88-
return self.execute(command)
88+
return self.execute(' '.join(command.split('\n')))
8989

9090
def execute_no_reconnect(self, command):
9191
if not command:

tests/suites/test_dml.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,28 @@ def test_11_select_all_hash(self):
241241
with self.assertRaises(tarantool.error.DatabaseError):
242242
space.select((), iterator=tarantool.const.ITERATOR_EQ)
243243

244+
def test_12_update_fields(self):
245+
self.srv.admin(
246+
"""
247+
do
248+
local sp = box.schema.create_space('sp', {
249+
format = {
250+
{ name = 'fir', type = 'unsigned' },
251+
{ name = 'sec', type = 'string' },
252+
{ name = 'thi', type = 'unsigned' },
253+
}
254+
})
255+
sp:create_index('pr', {
256+
parts = {1, 'unsigned'}
257+
})
258+
end
259+
""")
260+
self.con.insert('sp', [2, 'help', 4])
261+
self.assertSequenceEqual(
262+
self.con.update('sp', (2,), [('+', 'thi', 3)]),
263+
[[2, 'help', 7]]
264+
)
265+
244266
@classmethod
245267
def tearDownClass(self):
246268
self.srv.stop()

0 commit comments

Comments
 (0)