mirror of
https://github.com/yweber/lodel2.git
synced 2026-11-04 02:21:33 +01:00
Doing todo
Added a dummy EmFieldType_icon Added a test for EmType deletion with superiors
This commit is contained in:
parent
a86bbfbd49
commit
e757a3fb90
3 changed files with 82 additions and 30 deletions
|
|
@ -191,3 +191,24 @@ class EmField_mlstring(EmFieldType):
|
|||
|
||||
def sqlalchemy_args(self):
|
||||
return {'type_': VARCHAR(250), 'nullable': True, 'default': None}
|
||||
|
||||
class EmField_icon(EmFieldType):
|
||||
|
||||
def __init__(self):
|
||||
super(EmField_icon, self).__init__('icon')
|
||||
pass
|
||||
|
||||
def from_string(self,value):
|
||||
self.value = value
|
||||
|
||||
def to_sql(self, value=None):
|
||||
if value != None:
|
||||
value = str(value)
|
||||
return value
|
||||
|
||||
def sql_column(self):
|
||||
pass
|
||||
|
||||
def sqlalchemy_args(self):
|
||||
return {'type_': INTEGER, 'nullable': True, 'default': None}
|
||||
|
||||
|
|
|
|||
|
|
@ -221,4 +221,23 @@ class TestDeleteTypes(TypeTestCase):
|
|||
except EmComponentNotExistError:
|
||||
self.fail("The type was deleted but it has subordinates when deleted")
|
||||
pass
|
||||
|
||||
def testDeleteTypesInHierarchy(self):
|
||||
""" Testing if deletetion deletes properly links with superiors """
|
||||
type_name = self.emtype.name
|
||||
type_uid = self.emtype.uid
|
||||
self.emtype.add_superior(self.emtype2, EmNature.PARENT)
|
||||
self.emtype.delete()
|
||||
try:
|
||||
subs_dict = self.emtype2.subordinates()
|
||||
except EmComponentNotExistError:
|
||||
self.fail("The deleted type is style in the types hierarchu. Trying to retrieve it raises an EmComponentNotFoundError")
|
||||
|
||||
subsuid=[]
|
||||
for _, subs in subs_dict.items():
|
||||
subsuid += subs
|
||||
self.assertNotIn(type_uid, subsuid)
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import sqlalchemy as sql
|
|||
import EditorialModel
|
||||
from EditorialModel.components import EmComponent, EmComponentNotExistError
|
||||
from EditorialModel.fieldgroups import EmFieldGroup
|
||||
from EditorialModel.fields import EmField
|
||||
from EditorialModel.classtypes import EmNature, EmClassType
|
||||
import EditorialModel.fieldtypes as ftypes
|
||||
import EditorialModel.classes
|
||||
|
|
@ -18,13 +19,14 @@ import EditorialModel.classes
|
|||
# @see EditorialModel::components::EmComponent
|
||||
class EmType(EmComponent):
|
||||
table = 'em_type'
|
||||
table_hierarchy = 'em_type_hierarchy'
|
||||
ranked_in = 'class_id'
|
||||
|
||||
## @brief Specific EmClass fields
|
||||
# @see EditorialModel::components::EmComponent::_fields
|
||||
_fields = [
|
||||
('class_id', ftypes.EmField_integer),
|
||||
('icon', ftypes.EmField_integer),
|
||||
('icon', ftypes.EmField_icon),
|
||||
('sortcolumn', ftypes.EmField_char)
|
||||
]
|
||||
|
||||
|
|
@ -37,22 +39,37 @@ class EmType(EmComponent):
|
|||
# @throw EmComponentExistError if an EmType with this name but different attributes exists
|
||||
# @see EmComponent::__init__()
|
||||
#
|
||||
# @todo Remove hardcoded default value for icon
|
||||
# @todo check that em_class is an EmClass object
|
||||
# @todo check that em_class is an EmClass object (fieldtypes can handle it)
|
||||
def create(c, name, em_class, **em_component_args):
|
||||
return super(EmType, c).create(name=name, class_id=em_class.uid, icon=0, **em_component_args)
|
||||
|
||||
return super(EmType, c).create(name=name, class_id=em_class.uid, **em_component_args)
|
||||
|
||||
@property
|
||||
## Return an sqlalchemy table for type hierarchy
|
||||
# @return sqlalchemy em_type_hierarchy table object
|
||||
# @todo Don't hardcode table name
|
||||
def _table_hierarchy(self):
|
||||
return sql.Table(self.__class__.table_hierarchy, sqlutils.meta(self.db_engine()))
|
||||
|
||||
@property
|
||||
## Return the EmClassType of the type
|
||||
# @return EditorialModel.classtypes.*
|
||||
def classtype(self):
|
||||
return getattr(EmClassType, EditorialModel.classes.EmClass(self.class_id).classtype)
|
||||
|
||||
## @brief Delete an EmType
|
||||
# The deletion is only possible if a type is not linked by any EmClass
|
||||
# and if it has no subordinates
|
||||
# @return True if delete False if not deleted
|
||||
# @todo Check if the type is not linked by any EmClass
|
||||
# @todo Check if there is no other ''non-deletion'' conditions
|
||||
# @todo Delete it as subordinates for all its superiors
|
||||
def delete(self):
|
||||
subs = self.subordinates()
|
||||
if sum([len(subs[subnat]) for subnat in subs]) > 0:
|
||||
return False
|
||||
#Delete all relation with superiors
|
||||
for nature,sups in self.superiors().items():
|
||||
for sup in sups:
|
||||
self.del_superior(sup, nature)
|
||||
return super(EmType, self).delete()
|
||||
|
||||
|
||||
|
|
@ -103,8 +120,10 @@ class EmType(EmComponent):
|
|||
#
|
||||
# @param field EmField: The optional field to select
|
||||
# @return True if success False if failed
|
||||
# @throw TypeError
|
||||
# @todo change exception type and define return value and raise condition
|
||||
#
|
||||
# @throw TypeError if field is not an EmField instance
|
||||
# @throw ValueError if field is not optional or is not associated with this type
|
||||
# @see EmType::_opt_field_act()
|
||||
def select_field(self, field):
|
||||
return self._opt_field_act(field, True)
|
||||
|
||||
|
|
@ -114,7 +133,10 @@ class EmType(EmComponent):
|
|||
#
|
||||
# @param field EmField: The optional field to unselect
|
||||
# @return True if success False if fails
|
||||
# @throw TypeError
|
||||
#
|
||||
# @throw TypeError if field is not an EmField instance
|
||||
# @throw ValueError if field is not optional or is not associated with this type
|
||||
# @see EmType::_opt_field_act()
|
||||
def unselect_field(self, field):
|
||||
return self._opt_field_act(field, False)
|
||||
|
||||
|
|
@ -123,9 +145,12 @@ class EmType(EmComponent):
|
|||
# @param field EmField: The EmField to select or unselect
|
||||
# @param select bool: If True select field, else unselect it
|
||||
# @return True if success False if fails
|
||||
#
|
||||
# @throw TypeError if field is not an EmField instance
|
||||
# @throw ValueError if field is not optional or is not associated with this type
|
||||
def _opt_field_act(self, field, select=True):
|
||||
if not isinstance(field, EmField):
|
||||
raise TypeError("Excepted <class EmField> as field argument. But got "+str(type(field)))
|
||||
if not field in self.all_fields():
|
||||
raise ValueError("This field is not part of this type")
|
||||
if not field.optional:
|
||||
|
|
@ -149,7 +174,7 @@ class EmType(EmComponent):
|
|||
# @note Not conceptualized yet
|
||||
# @todo Conception
|
||||
def hooks(self):
|
||||
pass
|
||||
raise NotImplementedError()
|
||||
|
||||
## Add a new hook
|
||||
# @param hook EmHook: An EmHook instance
|
||||
|
|
@ -157,7 +182,7 @@ class EmType(EmComponent):
|
|||
# @note Not conceptualized yet
|
||||
# @todo Conception
|
||||
def add_hook(self, hook):
|
||||
pass
|
||||
raise NotImplementedError()
|
||||
|
||||
## Delete a hook
|
||||
# @param hook EmHook: An EmHook instance
|
||||
|
|
@ -166,22 +191,9 @@ class EmType(EmComponent):
|
|||
# @todo Conception
|
||||
# @todo Maybe we don't need a EmHook instance but just a hook identifier
|
||||
def del_hook(self,hook):
|
||||
pass
|
||||
|
||||
|
||||
@classmethod
|
||||
## Return an sqlalchemy table for type hierarchy
|
||||
# @return sqlalchemy em_type_hierarchy table object
|
||||
# @todo Don't hardcode table name
|
||||
def _tableHierarchy(cl):
|
||||
return sql.Table('em_type_hierarchy', sqlutils.meta(cl.db_engine()))
|
||||
|
||||
@property
|
||||
## Return the EmClassType of the type
|
||||
# @return EditorialModel.classtypes.*
|
||||
def classtype(self):
|
||||
return getattr(EmClassType, EditorialModel.classes.EmClass(self.class_id).classtype)
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
## @brief Get the list of subordinates EmType
|
||||
# Get a list of EmType instance that have this EmType for superior
|
||||
# @return Return a dict with relation nature as keys and values as a list of subordinates
|
||||
|
|
@ -207,7 +219,7 @@ class EmType(EmComponent):
|
|||
# @see EmType::subordinates(), EmType::superiors()
|
||||
def _subOrSup(self, sup = True):
|
||||
conn = self.db_engine().connect()
|
||||
htable = self.__class__._tableHierarchy()
|
||||
htable = self._table_hierarchy
|
||||
req = htable.select()
|
||||
if sup:
|
||||
req = req.where(htable.c.subordinate_id == self.uid)
|
||||
|
|
@ -255,7 +267,7 @@ class EmType(EmComponent):
|
|||
raise ValueError("Not allowed to put a different em_type as superior in a relation of nature '"+relation_nature+"'")
|
||||
|
||||
conn = self.db_engine().connect()
|
||||
htable = self.__class__._tableHierarchy()
|
||||
htable = self._table_hierarchy
|
||||
values = { 'subordinate_id': self.uid, 'superior_id': em_type.uid, 'nature': relation_nature }
|
||||
req = htable.insert(values=values)
|
||||
|
||||
|
|
@ -280,7 +292,7 @@ class EmType(EmComponent):
|
|||
raise ValueError("Invalid nature for add_superior : '"+relation_nature+"'. Allowed relations for this type are "+str(EmClassType.natures(self.classtype['name'])))
|
||||
|
||||
conn = self.db_engine().connect()
|
||||
htable = self.__class__._tableHierarchy()
|
||||
htable = self._table_hierarchy
|
||||
req = htable.delete(htable.c.superior_id == em_type.uid and htable.c.nature == relation_nature)
|
||||
conn.execute(req)
|
||||
conn.close()
|
||||
|
|
@ -296,7 +308,7 @@ class EmType(EmComponent):
|
|||
# @return A list of EmType objects
|
||||
def _linked_types_Db(self):
|
||||
conn = self.db_engine().connect()
|
||||
htable = self.__class__._tableHierarchy()
|
||||
htable = self._table_hierarchy
|
||||
req = htable.select(htable.c.superior_id, htable.c.subordinate_id)
|
||||
req = req.where(sql.or_(htable.c.subordinate_id == self.uid, htable.c.superior_id == self.uid))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue