Skip to content

Commit 1d3b241

Browse files
committed
update internal cached mapping upon graph version change
1 parent 5680907 commit 1d3b241

File tree

2 files changed

+83
-50
lines changed

2 files changed

+83
-50
lines changed

redisgraph/graph.py

+37-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from .util import *
22
from .query_result import QueryResult
3+
34
class Graph(object):
45
"""
56
Graph, collection of nodes and edges.
@@ -9,39 +10,59 @@ def __init__(self, name, redis_con):
910
"""
1011
Create a new graph.
1112
"""
12-
self.name = name
13+
self.name = name # Graph key
14+
self.version = None # Graph version
1315
self.redis_con = redis_con
1416
self.nodes = {}
1517
self.edges = []
1618
self._labels = [] # List of node labels.
1719
self._properties = [] # List of properties.
1820
self._relationshipTypes = [] # List of relation types.
1921

22+
def _refresh_schema(self):
23+
self._refresh_labels()
24+
self._refresh_relations()
25+
self._refresh_attributes()
26+
27+
def _refresh_labels(self):
28+
lbls = self.labels()
29+
30+
# Unpack data.
31+
self._labels = [None] * len(lbls)
32+
for i, l in enumerate(lbls):
33+
self._labels[i] = l[0]
34+
35+
def _refresh_relations(self):
36+
rels = self.relationshipTypes()
37+
38+
# Unpack data.
39+
self._relationshipTypes = [None] * len(rels)
40+
for i, r in enumerate(rels):
41+
self._relationshipTypes[i] = r[0]
42+
43+
def _refresh_attributes(self):
44+
props = self.propertyKeys()
45+
46+
# Unpack data.
47+
self._properties = [None] * len(props)
48+
for i, p in enumerate(props):
49+
self._properties[i] = p[0]
50+
2051
def get_label(self, idx):
2152
try:
2253
label = self._labels[idx]
2354
except IndexError:
24-
# Refresh graph labels.
25-
lbls = self.labels()
26-
# Unpack data.
27-
self._labels = [None] * len(lbls)
28-
for i, l in enumerate(lbls):
29-
self._labels[i] = l[0]
30-
55+
# Refresh labels.
56+
self._refresh_labels()
3157
label = self._labels[idx]
3258
return label
3359

3460
def get_relation(self, idx):
3561
try:
3662
relationshipType = self._relationshipTypes[idx]
3763
except IndexError:
38-
# Refresh graph relations.
39-
rels = self.relationshipTypes()
40-
# Unpack data.
41-
self._relationshipTypes = [None] * len(rels)
42-
for i, r in enumerate(rels):
43-
self._relationshipTypes[i] = r[0]
44-
64+
# Refresh relationship types.
65+
self._refresh_relations()
4566
relationshipType = self._relationshipTypes[idx]
4667
return relationshipType
4768

@@ -50,12 +71,7 @@ def get_property(self, idx):
5071
propertie = self._properties[idx]
5172
except IndexError:
5273
# Refresh properties.
53-
props = self.propertyKeys()
54-
# Unpack data.
55-
self._properties = [None] * len(props)
56-
for i, p in enumerate(props):
57-
self._properties[i] = p[0]
58-
74+
self._refresh_attributes()
5975
propertie = self._properties[idx]
6076
return propertie
6177

redisgraph/query_result.py

+46-29
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,28 @@
44
from prettytable import PrettyTable
55
from redis import ResponseError
66

7+
LABELS_ADDED = 'Labels added'
8+
NODES_CREATED = 'Nodes created'
9+
NODES_DELETED = 'Nodes deleted'
10+
RELATIONSHIPS_DELETED = 'Relationships deleted'
11+
PROPERTIES_SET = 'Properties set'
12+
RELATIONSHIPS_CREATED = 'Relationships created'
13+
INDICES_CREATED = "Indices created"
14+
INDICES_DELETED = "Indices deleted"
15+
CACHED_EXECUTION = "Cached execution"
16+
INTERNAL_EXECUTION_TIME = 'internal execution time'
17+
GRAPH_VERSION = 'Graph version'
18+
19+
STATS = [LABELS_ADDED, NODES_CREATED, PROPERTIES_SET, RELATIONSHIPS_CREATED,
20+
NODES_DELETED, RELATIONSHIPS_DELETED, INDICES_CREATED, INDICES_DELETED,
21+
CACHED_EXECUTION, INTERNAL_EXECUTION_TIME, GRAPH_VERSION]
722

823
class ResultSetColumnTypes(object):
924
COLUMN_UNKNOWN = 0
1025
COLUMN_SCALAR = 1
1126
COLUMN_NODE = 2 # Unused as of RedisGraph v2.1.0, retained for backwards compatibility.
1227
COLUMN_RELATION = 3 # Unused as of RedisGraph v2.1.0, retained for backwards compatibility.
1328

14-
1529
class ResultSetScalarTypes(object):
1630
VALUE_UNKNOWN = 0
1731
VALUE_NULL = 1
@@ -25,16 +39,6 @@ class ResultSetScalarTypes(object):
2539
VALUE_PATH = 9
2640

2741
class QueryResult(object):
28-
LABELS_ADDED = 'Labels added'
29-
NODES_CREATED = 'Nodes created'
30-
NODES_DELETED = 'Nodes deleted'
31-
RELATIONSHIPS_DELETED = 'Relationships deleted'
32-
PROPERTIES_SET = 'Properties set'
33-
RELATIONSHIPS_CREATED = 'Relationships created'
34-
INDICES_CREATED = "Indices created"
35-
INDICES_DELETED = "Indices deleted"
36-
CACHED_EXECUTION = "Cached execution"
37-
INTERNAL_EXECUTION_TIME = 'internal execution time'
3842

3943
def __init__(self, graph, response):
4044
self.graph = graph
@@ -48,9 +52,18 @@ def __init__(self, graph, response):
4852
if len(response) == 1:
4953
self.parse_statistics(response[0])
5054
else:
51-
self.parse_results(response)
55+
# start by parsing statistics, see if the reported graph version
56+
# matches the one we have
5257
self.parse_statistics(response[-1]) # Last element.
5358

59+
if(graph.version != self.graph_version):
60+
# graph version miss-match, this is an indication that
61+
# the graph schema was modified, sync it.
62+
graph.version = self.graph_version
63+
graph._refresh_schema()
64+
65+
self.parse_results(response)
66+
5467
def parse_results(self, raw_result_set):
5568
self.header = self.parse_header(raw_result_set)
5669

@@ -63,10 +76,12 @@ def parse_results(self, raw_result_set):
6376
def parse_statistics(self, raw_statistics):
6477
self.statistics = {}
6578

66-
stats = [self.LABELS_ADDED, self.NODES_CREATED, self.PROPERTIES_SET, self.RELATIONSHIPS_CREATED,
67-
self.NODES_DELETED, self.RELATIONSHIPS_DELETED, self.INDICES_CREATED, self.INDICES_DELETED,
68-
self.CACHED_EXECUTION, self.INTERNAL_EXECUTION_TIME]
69-
for s in stats:
79+
# decode statistics
80+
for idx, stat in enumerate(raw_statistics):
81+
if isinstance(stat, bytes):
82+
raw_statistics[idx] = stat.decode()
83+
84+
for s in STATS:
7085
v = self._get_value(s, raw_statistics)
7186
if v is not None:
7287
self.statistics[s] = v
@@ -223,53 +238,55 @@ def is_empty(self):
223238
@staticmethod
224239
def _get_value(prop, statistics):
225240
for stat in statistics:
226-
if isinstance(stat, bytes):
227-
stat = stat.decode()
228241
if prop in stat:
229242
return float(stat.split(': ')[1].split(' ')[0])
230243

231-
232244
return None
233245

234246
def _get_stat(self, stat):
235247
return self.statistics[stat] if stat in self.statistics else 0
236248

237249
@property
238250
def labels_added(self):
239-
return self._get_stat(self.LABELS_ADDED)
251+
return self._get_stat(LABELS_ADDED)
240252

241253
@property
242254
def nodes_created(self):
243-
return self._get_stat(self.NODES_CREATED)
255+
return self._get_stat(NODES_CREATED)
244256

245257
@property
246258
def nodes_deleted(self):
247-
return self._get_stat(self.NODES_DELETED)
259+
return self._get_stat(NODES_DELETED)
248260

249261
@property
250262
def properties_set(self):
251-
return self._get_stat(self.PROPERTIES_SET)
263+
return self._get_stat(PROPERTIES_SET)
252264

253265
@property
254266
def relationships_created(self):
255-
return self._get_stat(self.RELATIONSHIPS_CREATED)
267+
return self._get_stat(RELATIONSHIPS_CREATED)
256268

257269
@property
258270
def relationships_deleted(self):
259-
return self._get_stat(self.RELATIONSHIPS_DELETED)
271+
return self._get_stat(RELATIONSHIPS_DELETED)
260272

261273
@property
262274
def indices_created(self):
263-
return self._get_stat(self.INDICES_CREATED)
275+
return self._get_stat(INDICES_CREATED)
264276

265277
@property
266278
def indices_deleted(self):
267-
return self._get_stat(self.INDICES_DELETED)
279+
return self._get_stat(INDICES_DELETED)
268280

269281
@property
270282
def cached_execution(self):
271-
return self._get_stat(self.CACHED_EXECUTION) == 1
283+
return self._get_stat(CACHED_EXECUTION) == 1
272284

273285
@property
274286
def run_time_ms(self):
275-
return self._get_stat(self.INTERNAL_EXECUTION_TIME)
287+
return self._get_stat(INTERNAL_EXECUTION_TIME)
288+
289+
@property
290+
def graph_version(self):
291+
return self._get_stat(GRAPH_VERSION)
292+

0 commit comments

Comments
 (0)