Skip to content

Commit 5e3db94

Browse files
map datatype (#117)
* map datatype * Use an OrderedDict to represent maps * Restructure map return format * updated map compact format Co-authored-by: Jeffrey Lovitz <[email protected]>
1 parent 04e3f96 commit 5e3db94

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

redisgraph/graph.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def merge(self, pattern):
218218
return self.query(query)
219219

220220
# Procedures.
221-
def call_procedure(self, procedure, read_only=False, *args, **kwagrs):
221+
def call_procedure(self, procedure, *args, read_only=False, **kwagrs):
222222
args = [quote_string(arg) for arg in args]
223223
q = 'CALL %s(%s)' % (procedure, ','.join(args))
224224

redisgraph/query_result.py

+27-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from .exceptions import VersionMismatchException
55
from prettytable import PrettyTable
66
from redis import ResponseError
7+
from collections import OrderedDict
78

89
LABELS_ADDED = 'Labels added'
910
NODES_CREATED = 'Nodes created'
@@ -39,6 +40,7 @@ class ResultSetScalarTypes:
3940
VALUE_EDGE = 7
4041
VALUE_NODE = 8
4142
VALUE_PATH = 9
43+
VALUE_MAP = 10
4244

4345

4446
class QueryResult:
@@ -125,6 +127,14 @@ def parse_entity_properties(self, props):
125127

126128
return properties
127129

130+
def parse_string(self, cell):
131+
if isinstance(cell, bytes):
132+
return cell.decode()
133+
elif not isinstance(cell, str):
134+
return str(cell)
135+
else:
136+
return cell
137+
128138
def parse_node(self, cell):
129139
# Node ID (integer),
130140
# [label string offset (integer)],
@@ -156,6 +166,19 @@ def parse_path(self, cell):
156166
edges = self.parse_scalar(cell[1])
157167
return Path(nodes, edges)
158168

169+
def parse_map(self, cell):
170+
m = OrderedDict()
171+
n_entries = len(cell)
172+
173+
# A map is an array of key value pairs.
174+
# 1. key (string)
175+
# 2. array: (value type, value)
176+
for i in range(0, n_entries, 2):
177+
key = self.parse_string(cell[i])
178+
m[key] = self.parse_scalar(cell[i+1])
179+
180+
return m
181+
159182
def parse_scalar(self, cell):
160183
scalar_type = int(cell[0])
161184
value = cell[1]
@@ -165,12 +188,7 @@ def parse_scalar(self, cell):
165188
scalar = None
166189

167190
elif scalar_type == ResultSetScalarTypes.VALUE_STRING:
168-
if isinstance(value, bytes):
169-
scalar = value.decode()
170-
elif not isinstance(value, str):
171-
scalar = str(value)
172-
else:
173-
scalar = value
191+
scalar = self.parse_string(value)
174192

175193
elif scalar_type == ResultSetScalarTypes.VALUE_INTEGER:
176194
scalar = int(value)
@@ -202,6 +220,9 @@ def parse_scalar(self, cell):
202220
elif scalar_type == ResultSetScalarTypes.VALUE_PATH:
203221
scalar = self.parse_path(value)
204222

223+
elif scalar_type == ResultSetScalarTypes.VALUE_MAP:
224+
scalar = self.parse_map(value)
225+
205226
elif scalar_type == ResultSetScalarTypes.VALUE_UNKNOWN:
206227
print("Unknown scalar type\n")
207228

tests/functional/test_all.py

+13
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ def test_param(self):
102102
# All done, remove graph.
103103
redis_graph.delete()
104104

105+
def test_map(self):
106+
redis_graph = Graph('map', self.r)
107+
108+
query = "RETURN {a:1, b:'str', c:NULL, d:[1,2,3], e:True, f:{x:1, y:2}}"
109+
110+
actual = redis_graph.query(query).result_set[0][0]
111+
expected = {'a': 1, 'b': 'str', 'c': None, 'd': [1, 2, 3], 'e': True, 'f': {'x': 1, 'y': 2}}
112+
113+
self.assertEqual(actual, expected)
114+
115+
# All done, remove graph.
116+
redis_graph.delete()
117+
105118
def test_index_response(self):
106119
redis_graph = Graph('social', self.r)
107120

0 commit comments

Comments
 (0)