Skip to content

Commit c9f2bd3

Browse files
committed
Add basic support for IPROTO EVAL requests
1 parent ee14c9f commit c9f2bd3

File tree

5 files changed

+58
-9
lines changed

5 files changed

+58
-9
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*.pyc
22
*.pyo
33
*.wpr
4+
*~
45
/build/
56
/dist/
67
/MANIFEST

Diff for: tarantool/connection.py

+23
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
Request,
2626
RequestCall,
2727
RequestDelete,
28+
RequestEval,
2829
RequestInsert,
2930
RequestReplace,
3031
RequestPing,
@@ -281,6 +282,28 @@ def call(self, func_name, *args):
281282
response = self._send_request(request)
282283
return response
283284

285+
def eval(self, expr, *args):
286+
'''\
287+
Execute EVAL request. Eval Lua expression.
288+
289+
:param expr: Lua expression
290+
:type expr: str
291+
:param args: list of function arguments
292+
:type args: list or tuple
293+
294+
:rtype: `Response` instance
295+
'''
296+
assert isinstance(expr, str)
297+
298+
# This allows to use a tuple or list as an argument
299+
if len(args) == 1 and isinstance(args[0], (list, tuple)):
300+
args = args[0]
301+
302+
request = RequestEval(self, expr, args)
303+
response = self._send_request(request)
304+
return response
305+
306+
284307
def replace(self, space_name, values):
285308
'''
286309
Execute REPLACE request.

Diff for: tarantool/const.py

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
REQUEST_TYPE_DELETE = 5
2727
REQUEST_TYPE_CALL = 6
2828
REQUEST_TYPE_AUTHENTICATE = 7
29+
REQUEST_TYPE_EVAL = 8
2930
REQUEST_TYPE_ERROR = 1 << 15
3031

3132

Diff for: tarantool/request.py

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
REQUEST_TYPE_DELETE,
2727
REQUEST_TYPE_UPDATE,
2828
REQUEST_TYPE_CALL,
29+
REQUEST_TYPE_EVAL,
2930
REQUEST_TYPE_AUTHENTICATE
3031
)
3132

@@ -194,6 +195,13 @@ def __init__(self, conn, name, args):
194195

195196
self._bytes = self.header(len(request_body)) + request_body
196197

198+
class RequestEval(RequestCall):
199+
200+
'''
201+
Represents EVAL request
202+
'''
203+
request_type = REQUEST_TYPE_EVAL
204+
197205

198206
class RequestPing(Request):
199207

Diff for: tarantool/response.py

+25-9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import sys
55
import msgpack
6+
import yaml
67

78
from tarantool.const import (
89
IPROTO_CODE,
@@ -41,7 +42,7 @@ def __init__(self, conn, response):
4142
# created in the __new__(). But let it be.
4243
super(Response, self).__init__()
4344

44-
unpacker = msgpack.Unpacker(use_list = False)
45+
unpacker = msgpack.Unpacker(use_list = True)
4546
unpacker.feed(response)
4647
header = unpacker.unpack()
4748

@@ -57,12 +58,18 @@ def __init__(self, conn, response):
5758
if code == REQUEST_TYPE_OK:
5859
self._return_code = 0;
5960
self._completion_status = 0
60-
self.extend(body.get(IPROTO_DATA, []))
61+
self._data = body.get(IPROTO_DATA, None)
62+
# Backward-compatibility
63+
if isinstance(self._data, (list, tuple)):
64+
self.extend(self._data)
65+
else:
66+
self.append(self._data)
6167
else:
6268
# Separate return_code and completion_code
6369
self._return_message = body.get(IPROTO_ERROR, "")
6470
self._return_code = code & (REQUEST_TYPE_ERROR - 1)
6571
self._completion_status = 2
72+
self._data = None
6673
if self.conn.error:
6774
raise DatabaseError(self._return_code, self._return_message)
6875

@@ -105,6 +112,17 @@ def return_code(self):
105112
'''
106113
return self._return_code
107114

115+
@property
116+
def data(self):
117+
'''\
118+
:type: object
119+
120+
Required field in the server response.
121+
Contains list of tuples of SELECT, REPLACE and DELETE requests
122+
and arbitrary data for CALL.
123+
'''
124+
return self._data
125+
108126
@property
109127
def strerror(self):
110128
'''\
@@ -131,13 +149,11 @@ def __str__(self):
131149
132150
:rtype: str or None
133151
'''
134-
errstr = "---\n- error:\n errcode: {errname}\n errmsg: {errstr}\n..."
135152
if self.completion_status:
136-
return errstr.format(errname = self.strerror,
137-
errstr = self.return_message)
138-
table = ""
139-
if len(self):
140-
table = "\n"+"\n".join(["- "+str(list(k)) for k in self])
141-
return "---{0}\n...".format(table)
153+
return yaml.dump({ 'error': {
154+
'code': self.strerror[0],
155+
'reason': self.return_message
156+
}})
157+
return yaml.dump(self._data)
142158

143159
__repr__ = __str__

0 commit comments

Comments
 (0)