diff --git a/goblin/api.py b/goblin/api.py index ece472224136c2b35def526a9d63edf9bb061067..200bcd6bc2f220d7a96270afb05e3410cdaf158c 100644 --- a/goblin/api.py +++ b/goblin/api.py @@ -273,8 +273,20 @@ class VertexProperty(metaclass=meta.ElementMeta): __data_type__ = None - def __init__(self, value): + def __init__(self, data_type, *, value=None, default=None): + if isinstance(data_type, type): + data_type = data_type() + self.__data_type__ = data_type self._value = value + self._default = default + + @property + def default(self): + self._default + + @property + def data_type(self): + return self.__data_type__ @property def value(self): diff --git a/goblin/mapper.py b/goblin/mapper.py index 3521153ea6f87290774c39fe96ebd4ef8208e583..d2e87eec8d3023a57c0e70904c4341be163cabba 100644 --- a/goblin/mapper.py +++ b/goblin/mapper.py @@ -46,20 +46,20 @@ def map_edge_to_ogm(result, element, mapping): # DB <-> OGM Mapping -def create_mapping(namespace, properties): +def create_mapping(namespace, properties, vertex_properties): """Constructor for :py:class:`Mapping`""" if namespace.get('__type__', None): - return Mapping(namespace, properties) + return Mapping(namespace, properties, vertex_properties) class Mapping: """This class stores the information necessary to map between an OGM element and a DB element""" - def __init__(self, namespace, properties): + def __init__(self, namespace, properties, vertex_properties): self._label = namespace.get('__label__', None) or self._create_label() self._type = namespace['__type__'] self._properties = [] - self._map_properties(properties) + self._map_properties(properties, vertex_properties) @property def label(self): @@ -72,7 +72,7 @@ class Mapping: def _create_label(self): return inflection.underscore(self.__class__.__name__) - def _map_properties(self, properties): + def _map_properties(self, properties, vertex_properties): for name, prop in properties.items(): data_type = prop.data_type db_name = '{}__{}'.format(self._label, name) diff --git a/goblin/meta.py b/goblin/meta.py index b698e3c769391620331880fbb0a4d766242eaeec..a1ea9a9d9596db253d29ef39be00224ee8d0e5be 100644 --- a/goblin/meta.py +++ b/goblin/meta.py @@ -1,5 +1,7 @@ import logging +import inflection + from goblin import mapper from goblin import properties @@ -15,22 +17,28 @@ class ElementMeta(type): :py:class:`property.PropertyDescriptor`""" def __new__(cls, name, bases, namespace, **kwds): if bases: - namespace['__type__'] = bases[0].__name__.lower() + namespace['__type__'] = inflection.underscore(bases[0].__name__) props = {} + vertex_props = {} new_namespace = {} for k, v in namespace.items(): if isinstance(v, properties.Property): props[k] = v - if v.vertex_property: + v = properties.PropertyDescriptor( + k, v.data_type, default=v.default) + else: + element_type = getattr(v, '__type__', None) + if element_type == 'vertex_property': + vertex_props[k] = v + vertex_property_class = v.__class__ + vertex_property_class.__data_type__ = v.data_type v = properties.VertexPropertyDescriptor( - k, v.vertex_property, default=v.default) - else: - v = properties.PropertyDescriptor( - k, v.data_type, default=v.default) + k, vertex_property_class, default=v.default) new_namespace[k] = v new_namespace['__mapping__'] = mapper.create_mapping(namespace, - props) - logger.warning("Creating new Element class {}: {}".format( + props, + vertex_props) + logger.info("Creating new Element class {}: {}".format( name, new_namespace['__mapping__'])) result = type.__new__(cls, name, bases, new_namespace) return result diff --git a/goblin/properties.py b/goblin/properties.py index 793e6d6eb0bf0229e54eb9a1e23a98f2fe78c491..fed59b93704091705e48fc1a1f4cacbffe0bc721 100644 --- a/goblin/properties.py +++ b/goblin/properties.py @@ -48,11 +48,13 @@ class VertexPropertyDescriptor(PropertyDescriptor): vertex_property = [] for v in val: v = self._data_type.__data_type__.validate(v) - vertex_property.append(self._data_type(v)) + vertex_property.append( + self._data_type(self._data_type.__data_type__, value=v)) else: val = self._data_type.__data_type__.validate(val) - vertex_property = self._data_type(val) + vertex_property = self._data_type( + self._data_type.__data_type__, value=val) setattr(obj, self._name, vertex_property) @@ -62,13 +64,10 @@ class Property: descriptor = PropertyDescriptor - def __init__(self, data_type, *, vertex_property=None, default=None): + def __init__(self, data_type, *, default=None): if isinstance(data_type, type): data_type = data_type() self._data_type = data_type - if vertex_property: - vertex_property.__data_type__ = data_type - self._vertex_property = vertex_property self._default = default @property diff --git a/tests/test_properties.py b/tests/test_properties.py index 4c468701d019c3eaa9145f1849372c4186a4ac63..e21764fb5e018204f9eac3ddb59c3433a194333f 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -11,7 +11,7 @@ class TestVertexProperty(VertexProperty): class TestVertex(Vertex): __label__ = 'test_vertex' - name = Property(String, vertex_property=TestVertexProperty) + name = TestVertexProperty(String) address = Property(String)