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:
parent
27d178e531
commit
6af0b45f3f
6 changed files with 96 additions and 128 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 *
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue