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.3KB

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