No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

classes.py 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. # -*- coding: utf-8 -*-
  2. ## @file classes.py
  3. # @see EditorialModel::classes::EmClass
  4. import logging as logger
  5. from EditorialModel.components import EmComponent, EmComponentNotExistError, EmComponentExistError
  6. from Database import sqlutils
  7. import sqlalchemy as sql
  8. import EditorialModel.fieldtypes as ftypes
  9. import EditorialModel
  10. ## @brief Manipulate Classes of the Editorial Model
  11. # Create classes of object.
  12. # @see EmClass, EmType, EmFieldGroup, EmField
  13. # @todo sortcolumn handling
  14. class EmClass(EmComponent):
  15. table = 'em_class'
  16. ranked_in = 'classtype'
  17. ## @brief Specific EmClass fields
  18. # @see EditorialModel::components::EmComponent::_fields
  19. _fields = [
  20. ('classtype', ftypes.EmField_char),
  21. ('icon', ftypes.EmField_icon),
  22. ('sortcolumn', ftypes.EmField_char)
  23. ]
  24. ## Create a new class
  25. # @param name str: name of the new class
  26. # @param class_type EmClasstype: type of the class
  27. # @return An EmClass instance
  28. # @throw EmComponentExistError if an EmClass with this name and a different classtype exists
  29. @classmethod
  30. def create(cls, name, classtype, icon=None, sortcolumn='rank', **em_component_args):
  31. return cls._create_db(name=name, classtype=classtype['name'], icon=icon, sortcolumn=sortcolumn, **em_component_args)
  32. @classmethod
  33. ## Isolate SQL for EmClass::create
  34. # @return An instance of EmClass
  35. def _create_db(cls, name, classtype, icon, sortcolumn, **em_component_args):
  36. #Create a new entry in the em_class table
  37. result = super(EmClass, cls).create(name=name, classtype=classtype, icon=icon, sortcolumn=sortcolumn, **em_component_args)
  38. dbe = result.db_engine()
  39. conn = dbe.connect()
  40. #Create a new table storing LodelObjects of this EmClass
  41. meta = sql.MetaData()
  42. emclasstable = sql.Table(result.class_table_name, meta, sql.Column('uid', sql.VARCHAR(50), primary_key=True))
  43. emclasstable.create(conn)
  44. conn.close()
  45. return result
  46. @property
  47. ## @brief Return the table name used to stores data on this class
  48. def class_table_name(self):
  49. return self.name
  50. ## @brief Delete a class if it's ''empty''
  51. # If a class has no fieldgroups delete it
  52. # @return bool : True if deleted False if deletion aborded
  53. def delete(self):
  54. do_delete = True
  55. fieldgroups = self.fieldgroups()
  56. if len(fieldgroups) > 0:
  57. do_delete = False
  58. return False
  59. dbe = self.__class__.db_engine()
  60. meta = sqlutils.meta(dbe)
  61. #Here we have to give a connection
  62. class_table = sql.Table(self.name, meta)
  63. meta.drop_all(tables=[class_table], bind=dbe)
  64. return super(EmClass, self).delete()
  65. ## Retrieve list of the field_groups of this class
  66. # @return A list of fieldgroups instance
  67. def fieldgroups(self):
  68. records = self._fieldgroups_db()
  69. fieldgroups = [EditorialModel.fieldgroups.EmFieldGroup(int(record.uid)) for record in records]
  70. return fieldgroups
  71. ## Isolate SQL for EmClass::fieldgroups
  72. # @return An array of dict (sqlalchemy fetchall)
  73. def _fieldgroups_db(self):
  74. dbe = self.__class__.db_engine()
  75. emfg = sql.Table(EditorialModel.fieldgroups.EmFieldGroup.table, sqlutils.meta(dbe))
  76. req = emfg.select().where(emfg.c.class_id == self.uid)
  77. conn = dbe.connect()
  78. res = conn.execute(req)
  79. return res.fetchall()
  80. ## Retrieve list of fields
  81. # @return fields [EmField]:
  82. def fields(self):
  83. fieldgroups = self.fieldgroups()
  84. fields = []
  85. for fieldgroup in fieldgroups:
  86. fields += fieldgroup.fields()
  87. return fields
  88. ## Retrieve list of type of this class
  89. # @return types [EmType]:
  90. def types(self):
  91. records = self._types_db()
  92. types = [EditorialModel.types.EmType(int(record.uid)) for record in records]
  93. return types
  94. ## Isolate SQL for EmCLass::types
  95. # @return An array of dict (sqlalchemy fetchall)
  96. def _types_db(self):
  97. dbe = self.__class__.db_engine()
  98. emtype = sql.Table(EditorialModel.types.EmType.table, sqlutils.meta(dbe))
  99. req = emtype.select().where(emtype.c.class_id == self.uid)
  100. conn = dbe.connect()
  101. res = conn.execute(req)
  102. return res.fetchall()
  103. ## Add a new EmType that can ben linked to this class
  104. # @param em_type EmType: type to link
  105. # @return success bool: done or not
  106. def link_type(self, em_type):
  107. table_name = self.name + '_' + em_type.name
  108. self._link_type_db(table_name)
  109. return True
  110. def _link_type_db(self, table_name):
  111. # Create a new table storing additionnal fields for the relation between the linked type and this EmClass
  112. conn = self.__class__.db_engine().connect()
  113. meta = sql.MetaData()
  114. emlinketable = sql.Table(table_name, meta, sql.Column('uid', sql.VARCHAR(50), primary_key=True))
  115. emlinketable.create(conn)
  116. conn.close()
  117. ## Retrieve list of EmType that are linked to this class
  118. # @return types [EmType]:
  119. def linked_types(self):
  120. return self._linked_types_db()
  121. def _linked_types_db(self):
  122. dbe = self.__class__.db_engine()
  123. meta = sql.MetaData()
  124. meta.reflect(dbe)
  125. linked_types = []
  126. for table in meta.tables.values():
  127. table_name_elements = table.name.split('_')
  128. if len(table_name_elements) == 2:
  129. linked_types.append(EditorialModel.types.EmType(table_name_elements[1]))
  130. return linked_types