diff --git a/goblin/manager.py b/goblin/manager.py index f0b352bfa97ec82ceaeee7d8e1e6c0a06f46c058..56aa775ca94376abddb6dafe4a40e17d4a20dbfd 100644 --- a/goblin/manager.py +++ b/goblin/manager.py @@ -47,6 +47,11 @@ class ListVertexPropertyManager(list, VertexPropertyManager): def __init__(self, data_type, vertex_prop, card, obj): VertexPropertyManager.__init__(self, data_type, vertex_prop, card) list.__init__(self, obj) + self._vp_map = {} + + @property + def vp_map(self): + return self._vp_map def append(self, val): vp = self._vertex_prop(self._data_type, card=self._card) diff --git a/goblin/mapper.py b/goblin/mapper.py index f322ed8ef480b6beb0a6b62287caa0bef4a2cd21..78889843afbeec3281c3b2405d796fbc6a3fab9b 100644 --- a/goblin/mapper.py +++ b/goblin/mapper.py @@ -60,20 +60,20 @@ def get_metaprops(vertex_property, mapping): def map_vertex_to_ogm(result, props, element, *, mapping=None): """Map a vertex returned by DB to OGM vertex""" - props.pop('id') label = props.pop('label') for db_name, value in props.items(): - metaprop_dict = {} + metaprops = [] if len(value) > 1: values = [] for v in value: if isinstance(v, dict): val = v.pop('value') v.pop('key') - v.pop('id') + vid = v.pop('id') if v: - metaprop_dict[val] = v + v['id'] = vid + metaprops.append((val, v)) values.append(val) else: values.append(v) @@ -83,21 +83,22 @@ def map_vertex_to_ogm(result, props, element, *, mapping=None): if isinstance(value, dict): val = value.pop('value') value.pop('key') - value.pop('id') + vid = value.pop('id') if value: - metaprop_dict[val] = value + value['id'] = vid + metaprops.append((val, value)) value = val name, data_type = mapping.db_properties.get(db_name, (db_name, None)) if data_type: value = data_type.to_ogm(value) setattr(element, name, value) - if metaprop_dict: + if metaprops: vert_prop = getattr(element, name) if hasattr(vert_prop, 'mapper_func'): # Temporary hack for managers - vert_prop.mapper_func(metaprop_dict, vert_prop) + vert_prop.mapper_func(metaprops, vert_prop) else: - vert_prop.__mapping__.mapper_func(metaprop_dict, vert_prop) + vert_prop.__mapping__.mapper_func(metaprops, vert_prop) setattr(element, '__label__', label) setattr(element, 'id', result.id) return element @@ -105,8 +106,19 @@ def map_vertex_to_ogm(result, props, element, *, mapping=None): def map_vertex_property_to_ogm(result, element, *, mapping=None): """Map a vertex returned by DB to OGM vertex""" - for val, metaprops in result.items(): - if isinstance(element, (list, set)): + for (val, metaprops) in result: + if isinstance(element, list): + current = element.vp_map.get(metaprops['id']) + # This whole system needs to be reevaluated + if not current: + current = element(val) + if isinstance(current, list): + for vp in current: + if not hasattr(vp, '_id'): + element.vp_map[metaprops['id']] = vp + current = vp + break + elif isinstance(element, set): current = element(val) else: current = element diff --git a/goblin/session.py b/goblin/session.py index ca0530b76dbe924eda37aef812cf3f7e730dc7a0..d1b4f4c875eec7c8c8828365bb88ecc816f4cda7 100644 --- a/goblin/session.py +++ b/goblin/session.py @@ -449,6 +449,7 @@ class Session: result = await self._simple_traversal(traversal, vertex) if metaprops: removals = await self._add_metaprops(result, metaprops, vertex) + # This can be tested for/removed for db_name, key, value in removals: await self._g.V(Binding('vid', vertex.id)).properties( db_name).has(key, value).drop().next() @@ -468,18 +469,22 @@ class Session: async def _add_metaprops(self, result, metaprops, vertex): potential_removals = [] for metaprop in metaprops: + # Make sure to get vp ids here. db_name, (binding, value), metaprops = metaprop + # Make sure to get vp ids here. for key, val in metaprops.items(): if val: - prop_name = vertex.__mapping__.db_properties[db_name][0] - vp = vertex.__properties__[prop_name] - if vp.cardinality == Cardinality.single: - traversal = self._g.V(Binding('vid', result.id)).properties( - db_name).property(key, val) - else: - traversal = self._g.V(Binding('vid', result.id)).properties( - db_name).hasValue(value).property(key, val) - await traversal.iterate() + # prop_name = vertex.__mapping__.db_properties[db_name][0] + # vp = vertex.__properties__[prop_name] + # # Select and add by id here if possible + # if vp.cardinality == Cardinality.single: + # traversal = self._g.V(Binding('vid', result.id)).properties( + # db_name).property(key, val) + # else: + # traversal = self._g.V(Binding('vid', result.id)).properties( + # db_name).hasValue(value).property(key, val) + # await traversal.iterate() + pass else: potential_removals.append((db_name, key, value)) return potential_removals @@ -489,6 +494,8 @@ class Session: potential_removals = [] potential_metaprops = [] for card, db_name, val, metaprops in props: + if not metaprops: + metaprops = {} if val is not None: key = ('k' + str(binding), db_name) val = ('v' + str(binding), val) @@ -500,9 +507,13 @@ class Session: card = Cardinality.set_ else: card = Cardinality.single - traversal = traversal.property(card, key, val) + metas = [j for i in zip( + metaprops.keys(), metaprops.values()) for j in i] + traversal = traversal.property(card, key, val, *metas) else: - traversal = traversal.property(key, val) + metas = [j for i in zip( + metaprops.keys(), metaprops.values()) for j in i] + traversal = traversal.property(key, val, *metas) binding += 1 if metaprops: potential_metaprops.append((db_name, val, metaprops))