Нема описа
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.

lerelation.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #-*- coding: utf-8 -*-
  2. import copy
  3. import EditorialModel.fieldtypes.leo as ft_leo
  4. from . import lecrud
  5. from . import leobject
  6. ## @brief Main class for relations
  7. class _LeRelation(lecrud._LeCrud):
  8. ## @brief Handles the superior
  9. _lesup_fieldtype = {'lesup': ft_leo.EmFieldType(True)}
  10. ## @brief Handles the subordinate
  11. _lesub_fieldtype = {'lesub': ft_leo.EmFieldType(False) }
  12. ## @brief Stores the list of fieldtypes that are common to all relations
  13. _rel_fieldtypes = dict()
  14. def __init__(self, rel_id, **kwargs):
  15. self.id_relation = rel_id
  16. ## @brief Forge a filter to match the superior
  17. @classmethod
  18. def sup_filter(self, leo):
  19. if isinstance(leo, leobject._LeObject):
  20. return ('lesup', '=', leo)
  21. ## @brief Forge a filter to match the superior
  22. @classmethod
  23. def sub_filter(self, leo):
  24. if isinstance(leo, leobject._LeObject):
  25. return ('lesub', '=', leo)
  26. ## @return a dict with field name as key and fieldtype instance as value
  27. @classmethod
  28. def fieldtypes(cls):
  29. rel_ft = dict()
  30. rel_ft.update(cls._uid_fieldtype)
  31. rel_ft.update(cls._lesup_fieldtype)
  32. rel_ft.update(cls._lesub_fieldtype)
  33. rel_ft.update(cls._rel_fieldtypes)
  34. if cls.implements_lerel2type():
  35. rel_ft.update(cls._rel_attr_fieldtypes)
  36. return rel_ft
  37. @classmethod
  38. def _prepare_relational_fields(cls, field):
  39. return lecrud.LeApiQueryError("Relational field '%s' given but %s doesn't is not a LeObject" % (field,
  40. cls.__name__))
  41. ## @brief Prepare filters before sending them to the datasource
  42. # @param cls : Concerned class
  43. # @param filters_l list : List of filters
  44. # @return prepared and checked filters
  45. @classmethod
  46. def _prepare_filters(cls, filters_l):
  47. filters = list()
  48. res = list()
  49. rel = list()
  50. for filter_item in filters_l:
  51. if isinstance(filter_item, tuple):
  52. filters.append(filter_item)
  53. else:
  54. filter_item_data = filter_item.split(" ")
  55. if len(filter_item_data) == 3:
  56. if filter_item_data[0] in cls._lesub_fieldtype.keys():
  57. filter_item_data[2] = cls._lesub_fieldtype[filter_item_data[0]].construct_data(
  58. cls,
  59. filter_item_data[0],
  60. {filter_item_data[0]: int(filter_item_data[2])}
  61. )
  62. elif filter_item_data[0] in cls._lesup_fieldtype.keys():
  63. filter_item_data[2] = cls._lesup_fieldtype[filter_item_data[0]].construct_data(
  64. cls,
  65. filter_item_data[0],
  66. {filter_item_data[0]: int(filter_item_data[2])}
  67. )
  68. filters.append(tuple(filter_item_data))
  69. for field, operator, value in filters:
  70. if field.startswith('superior') or field.startswith('subordinate'):
  71. rel.append((field, operator, value))
  72. else:
  73. res.append((field, operator, value))
  74. return (res, rel)
  75. @classmethod
  76. ## @brief deletes a relation between two objects
  77. # @param filters_list list
  78. # @param target_class str
  79. def delete(cls, filters_list, target_class):
  80. filters, rel_filters = cls._prepare_filters(filters_list)
  81. if isinstance(target_class, str):
  82. target_class = cls.name2class(target_class)
  83. ret = cls._datasource.delete(target_class, filters)
  84. return True if ret == 1 else False
  85. ## @brief Abstract class to handle hierarchy relations
  86. class _LeHierarch(_LeRelation):
  87. ## @brief Delete current instance from DB
  88. def delete(self):
  89. lecrud._LeCrud._delete(self)
  90. ## @brief Abstract class to handle rel2type relations
  91. class _LeRel2Type(_LeRelation):
  92. ## @brief Stores the list of fieldtypes handling relations attributes
  93. _rel_attr_fieldtypes = dict()
  94. ## @brief Delete current instance from DB
  95. def delete(self):
  96. lecrud._LeCrud._delete(self)
  97. ## @brief Given a superior and a subordinate, returns the classname of the give rel2type
  98. # @param lesupclass LeClass : LeClass child class (can be a LeType or a LeClass child)
  99. # @param lesubclass LeType : A LeType child class
  100. # @return a name as string
  101. @staticmethod
  102. def relname(lesupclass, lesubclass):
  103. supname = lesupclass._leclass.__name__ if lesupclass.implements_letype() else lesupclass.__name__
  104. subname = lesubclass.__name__
  105. return "Rel_%s2%s" % (supname, subname)