1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2026-11-04 02:21:33 +01:00

Code factorization on EmType select and unselect fields. Added comparison capabilities to EmComponent (and childs)

Implemented __hash__ and __eq__ for EmComponent (based on class name and uid) to test equality betwenn two instance. Allows to use "instance in instance_list" syntax
This commit is contained in:
Yann 2015-07-02 14:35:43 +02:00
commit 6af0b45f3f
6 changed files with 96 additions and 128 deletions

View file

@ -106,6 +106,16 @@ class EmComponent(object):
self._fields[name].from_python(value)
else:
object.__setattr__(self, name, value)
## @brief Hash function that allows to compare two EmComponent
# @return EmComponent+ClassName+uid
def __hash__(self):
return "EmComponent"+self.__class__.__name__+str(self.uid)
## @brief Test if two EmComponent are "equals"
# @return True or False
def __eq__(self, other):
return self.__class__ == other.__class__ and self.uid == other.uid
## Lookup in the database properties of the object to populate the properties
# @throw EmComponentNotExistError if the instance is not anymore stored in database

View file

@ -1,105 +0,0 @@
#-*- coding: utf-8 -*-
from EditorialModel.fieldtypes import EmField_integer
from EditorialModel.components import EmComponent
from Database import sqlutils
import sqlalchemy as sqla
import logging
logger = logging.getLogger('Lodel2.EditorialModel')
## Em_Field_Type (Class)
#
# Represents an association between a field and a type
class Em_Field_Type(object):
table = 'em_field_type'
_fields = [('type_id', EmField_integer), ('field_id', EmField_integer)]
## __init__ (Function)
#
# Instanciates an Em_Field_Type object with data fetched from the database
#
# @param type_id integer: Identifier of the type
# @param field_id integer: Identifier of the field
def __init__(self, type_id, field_id):
self.table = Em_Field_Type.table
self._fields = self.__class__._fields
self.type_id = type_id
self.field_id = field_id
## Create (Function)
#
# Creates a relation between a field and a type
#
# @static
#
# @param emType EmType: Object representing the Type
# @param emField EmField: Object representing the Field
# @return Em_Field_Type object
@classmethod
def create(cls, em_type, em_field):
values = {
'type_id': em_type.uid,
'field_id': em_field.uid
}
created_relation = Em_Field_Type._create_db(**values)
return created_relation
@classmethod
def _create_db(cls, **kwargs):
dbe = EmComponent.db_engine()
conn = dbe.connect()
table = sqla.Table(cls.table, sqlutils.meta(dbe))
req = table.insert(kwargs)
res = conn.execute(req)
conn.close()
return Em_Field_Type(kwargs['type_id'], kwargs['field_id'])
## Delete (Function)
#
# Deletes a relation between a field and a type
#
# @return Boolean
def delete(self):
return self._delete_db()
def _delete_db(self):
dbe = EmComponent.db_engine()
table = sqla.Table(self.table, sqlutils.meta(dbe))
req = table.delete().where(table.c.type_id == self.type_id).where(table.c.field_id == self.field_id)
conn = dbe.connect()
try:
conn.execute(req)
res = True
except:
res = False
conn.close()
return res
## Exists (Function)
#
# Checks if a the relation exists in the database
#
# @return True if success, False if failure
def exists(self):
return self._exists_db()
## _ExistsDb (Function)
#
# Queries the database to see if a relation exists or not
#
# @return True if success, False if failure
def _exists_db(self):
dbe = EmComponent.db_engine()
table = sqla.Table(self.table, sqlutils.meta(dbe))
req = table.select().where(table.c.type_id == self.type_id).where(table.c.field_id == self.field_id)
conn = dbe.connect()
res = conn.execute(req).fetchall()
conn.close()
return len(res) > 0

View file

@ -12,7 +12,6 @@ from EditorialModel.classes import EmClass
from EditorialModel.classtypes import EmClassType
from EditorialModel.types import EmType
from EditorialModel.fieldgroups import EmFieldGroup
from EditorialModel.fields_types import Em_Field_Type
from EditorialModel.test.utils import *
from EditorialModel.fieldtypes import *

View file

@ -12,7 +12,6 @@ from EditorialModel.classtypes import EmClassType, EmNature
from EditorialModel.components import EmComponent, EmComponentNotExistError
from EditorialModel.fieldgroups import EmFieldGroup
from EditorialModel.fieldtypes import *
from EditorialModel.fields_types import Em_Field_Type
from EditorialModel.fields import EmField
from EditorialModel.test.utils import *
from Database import sqlutils
@ -44,8 +43,11 @@ def setUpModule():
EmType.create(name='type7', em_class=emclass4)
emfieldgroup = EmFieldGroup.create(name='fieldgroup1', em_class=emclass1)
emfieldgroup2 = EmFieldGroup.create(name='fieldgroup2', em_class=emclass2)
emfieldtype = get_field_type('integer')
EmField.create(name='field1', fieldgroup=emfieldgroup, fieldtype=emfieldtype, rel_to_type_id=emtype.uid)
EmField.create(name='field2', fieldgroup=emfieldgroup2, fieldtype=emfieldtype, optional=True)
EmField.create(name='field3', fieldgroup=emfieldgroup2, fieldtype=emfieldtype, optional=False)
saveDbState(TEST_TYPE_DBNAME)
@ -69,18 +71,34 @@ class TypeTestCase(TestCase):
self.emfieldgroup = EmFieldGroup('fieldgroup1')
self.emfieldtype = get_field_type('integer')
self.emfield = EmField('field1')
self.emfield2 = EmField('field2')
self.emfield3 = EmField('field3')
pass
class TestSelectField(TypeTestCase):
def testSelectField(self):
""" Testing optionnal field selection """
self.emtype.select_field(self.emfield)
self.assertIsNotNone(Em_Field_Type(self.emtype.uid, self.emfield.uid))
self.emtype.select_field(self.emfield2)
#a bit queick and dirty
self.assertIn(self.emfield2, self.emtype.selected_fields())
pass
def testUnselectField(self):
""" Testing optionnal field unselection """
self.emtype.unselect_field(self.emfield)
self.assertFalse(Em_Field_Type(self.emtype.uid, self.emfield.uid).exists())
self.emtype.select_field(self.emfield2)
self.emtype.unselect_field(self.emfield2)
self.assertNotIn(self.emfield2, self.emtype.selected_fields())
pass
def testSelectFieldInvalid(self):
""" Testing optionnal field selection with invalid fields """
with self.assertRaises(ValueError, msg="But the field was not optionnal"):
self.emtype.select_field(self.emfield3)
with self.assertRaises(ValueError, msg="But the field was not part of this type"):
self.emtype.select_field(self.emfield)
pass
class TestLinkedTypes(TypeTestCase):
@unittest.skip("Not yet implemented")

View file

@ -1,9 +1,9 @@
#-*- coding: utf-8 -*-
from EditorialModel.fields_types import Em_Field_Type
from Database import sqlutils
import sqlalchemy as sql
import EditorialModel
from EditorialModel.components import EmComponent, EmComponentNotExistError
from EditorialModel.fieldgroups import EmFieldGroup
from EditorialModel.classtypes import EmNature, EmClassType
@ -68,37 +68,82 @@ class EmType(EmComponent):
return [ EmFieldGroup(row['uid']) for row in rows ]
## Get the list of associated fields
## Get the list of all Emfield possibly associated with this type
# @return A list of EmField instance
# @todo handle optionnal fields
def fields(self):
def all_fields(self):
res = []
for fguid in self.field_groups():
res += EmFieldGroup(fguid).fields()
for fieldgroup in self.field_groups():
res += fieldgroup.fields()
return res
pass
## Return selected optional field
# @return A list of EmField instance
def selected_fields(self):
dbe = self.db_engine()
meta = sqlutils.meta(dbe)
conn = dbe.connect()
table = sql.Table('em_field_type', meta)
res = conn.execute(table.select().where(table.c.type_id == self.uid))
return [ EditorialModel.fields.EmField(row['field_id']) for row in res.fetchall()]
## Return the list of associated fields
# @return A list of EmField instance
def fields(self):
result = list()
for field in self.all_fields():
if not field.optional:
result.append(field)
return result+selected_fields
## Select_field (Function)
#
# Indicates that an optional field is used
#
# @param field EmField: The optional field to select
# @throw ValueError, TypeError
# @return True if success False if failed
# @throw TypeError
# @todo change exception type and define return value and raise condition
def select_field(self, field):
Em_Field_Type.create(self, field)
return self._opt_field_act(field, True)
## Unselect_field (Function)
#
# Indicates that an optional field will not be used
#
# @param field EmField: The optional field to unselect
# @throw ValueError, TypeError
# @todo change exception type and define return value and raise condition
# @return True if success False if fails
# @throw TypeError
def unselect_field(self, field):
emFieldType = Em_Field_Type(self.uid, field.uid)
emFieldType.delete()
del emFieldType
return self._opt_field_act(field, False)
## @brief Select or unselect an optional field
# @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 field in self.all_fields():
raise ValueError("This field is not part of this type")
if not field.optional:
raise ValueError("This field is not optional")
dbe = self.db_engine()
meta = sqlutils.meta(dbe)
conn = dbe.connect()
table = sql.Table('em_field_type', meta)
if select:
req = table.insert({'type_id': self.uid, 'field_id': field.uid})
else:
req = table.delete().where(table.c.type_id == self.uid and table.c.field_id == field.uid)
res = conn.execute(req)
conn.close()
return bool(res)
## Get the list of associated hooks
# @note Not conceptualized yet