17
17
# See the License for the specific language governing permissions and
18
18
# limitations under the License.
19
19
20
-
20
+ import inspect
21
21
from codecs import decode
22
22
from io import BytesIO
23
23
from struct import pack as struct_pack
@@ -85,7 +85,9 @@ def validate_validations(validations, type_name):
85
85
for validation in validations :
86
86
if not validation (fields ):
87
87
raise ValueError (
88
- f"Invalid { type_name } struct received { self } " )
88
+ f"Invalid { type_name } struct received.\n "
89
+ f"validation failed: { inspect .getsource (validation )} "
90
+ f" { self } " )
89
91
90
92
def verify_node_3_up ():
91
93
validations = [
@@ -163,6 +165,7 @@ def verify_relationship_5_up():
163
165
return
164
166
except ValueError as _ :
165
167
pass
168
+
166
169
validations = [
167
170
lambda f : len (f ) == 8 ,
168
171
lambda f : (isinstance (f [0 ], int ) or f [0 ] is None ),
@@ -178,26 +181,25 @@ def verify_relationship_5_up():
178
181
validate_validations (validations , "V5_Relationship" )
179
182
180
183
def verify_path ():
181
- if ( len ( fields ) != 3
182
- or not isinstance ( fields [ 0 ], list )
183
- or not all (isinstance (n , Structure )
184
- and n .tag == StructTag .node
185
- and n .fields [0 ] in fields [2 ] # id is used
186
- for n in fields [0 ])
187
- or not isinstance (fields [1 ], list )
188
- or not all (isinstance (rel , Structure )
189
- and rel .tag == StructTag .unbound_relationship
190
- and rel .fields [0 ] in fields [2 ] # id is used
191
- for rel in fields [1 ])
192
- or not isinstance (fields [2 ], list )
193
- or not all (isinstance (id_ , int )
184
+ validations = [
185
+ lambda f : len ( f ) == 3 ,
186
+ lambda f : all (isinstance (n , Structure )
187
+ and n .tag == StructTag .node
188
+ and n .fields [0 ] in f [2 ] # id is used
189
+ for n in f [0 ]),
190
+ lambda f : isinstance (f [1 ], list ),
191
+ lambda f : all (isinstance (rel , Structure )
192
+ and rel .tag == StructTag .unbound_relationship
193
+ and rel .fields [0 ] in f [2 ] # id is used
194
+ for rel in f [1 ]),
195
+ lambda f : isinstance (f [2 ], list ),
196
+ lambda f : all (isinstance (id_ , int )
194
197
# id exists in nodes or relationships
195
198
and id_ in {s .fields [0 ]
196
- for s in fields [0 ] + fields [1 ]}
197
- for id_ in fields [2 ])):
198
- raise ValueError (
199
- "Invalid Path struct received %r" % self
200
- )
199
+ for s in f [0 ] + f [1 ]}
200
+ for id_ in f [2 ])
201
+ ]
202
+ # validate_validations(validations, "Path")
201
203
202
204
def build_generic_verifier (types , name ):
203
205
def verify ():
@@ -350,20 +352,55 @@ def from_jolt_type(cls, jolt: jolt_types.JoltType):
350
352
jolt .element_id , jolt .start_node_element_id ,
351
353
jolt .end_node_element_id )
352
354
if isinstance (jolt , jolt_types .JoltPath ):
353
- # Node structs
355
+ uniq_nodes = []
356
+ uniq_rels = []
357
+ ids = []
354
358
nodes = []
359
+ rels = []
360
+ # Node structs
361
+ node_idxs = {}
362
+ node_idx = 0
355
363
for node in jolt .path [::2 ]:
356
- node = cls .from_jolt_type (node )
357
- if node not in nodes :
358
- nodes .append (node )
364
+ nodes .append (node )
365
+ map_node = cls (StructTag .node , node .id , node .labels ,
366
+ node .properties )
367
+ if map_node not in uniq_nodes :
368
+ node_idxs [str (node .id )] = node_idx
369
+ node_idx = node_idx + 1
370
+ # nodesDict[str(node.id)] = node
371
+ uniq_nodes .append (map_node )
372
+
359
373
# UnboundRelationship structs
360
- rels = []
374
+
375
+ rel_idxs = {}
376
+ rel_idx = 1
361
377
for rel in jolt .path [1 ::2 ]:
362
- rel = cls .from_jolt_type (rel )
363
- if rel not in rels :
364
- rels .append (rel )
365
- ids = [e .id for e in jolt .path ]
366
- return cls (StructTag .path , nodes , rels , ids )
378
+ rels .append (rel )
379
+ ub_rel = cls (StructTag .unbound_relationship , rel .id ,
380
+ rel .rel_type ,
381
+ rel .properties )
382
+ if ub_rel not in uniq_rels :
383
+ rel_idxs [str (rel .id )] = rel_idx
384
+ rel_idx = rel_idx + 1
385
+ # relsDict[rel.id_] = rel
386
+ uniq_rels .append (ub_rel )
387
+
388
+ last_node = nodes [0 ]
389
+ for i in range (1 , (len (rels )* 2 )+ 1 ):
390
+ if i % 2 == 0 :
391
+ last_node = nodes [int (i / 2 )]
392
+ index = node_idxs [str (last_node .id )]
393
+ ids .append (index )
394
+ else :
395
+ rel = rels [int (i / 2 )]
396
+ index = rel_idxs [str (rel .id )]
397
+ # print(f"{rel}")
398
+ if last_node .id == rel .start_node_id :
399
+ ids .append (index )
400
+ else :
401
+ ids .append (- index )
402
+
403
+ return cls (StructTag .path , uniq_nodes , uniq_rels , ids )
367
404
raise TypeError ("Unsupported jolt type: {}" .format (type (jolt )))
368
405
369
406
def to_jolt_type (self ):
0 commit comments