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.

utils.py 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # -*- coding: utf-8 -*-
  2. import pymongo
  3. collection_prefix = {
  4. 'relation': 'rel_',
  5. 'collection': 'class_'
  6. }
  7. LODEL_OPERATORS_MAP = {
  8. '=': {'name': '$eq', 'value_type': None},
  9. '<=': {'name': '$lte', 'value_type': None},
  10. '>=': {'name': '$gte', 'value_type': None},
  11. '!=': {'name': '$ne', 'value_type': None},
  12. '<': {'name': '$lt', 'value_type': None},
  13. '>': {'name': '$gt', 'value_type': None},
  14. 'in': {'name': '$in', 'value_type': list},
  15. 'not in': {'name': '$nin', 'value_type': list},
  16. 'OR': {'name': '$or', 'value_type': list},
  17. 'AND': {'name': '$and', 'value_type': list}
  18. }
  19. LODEL_SORT_OPERATORS_MAP = {
  20. 'ASC': pymongo.ASCENDING,
  21. 'DESC': pymongo.DESCENDING
  22. }
  23. MONGODB_SORT_OPERATORS_MAP = {
  24. 'ASC': 1,
  25. 'DESC': -1
  26. }
  27. ## @brief Returns a collection name given a Emclass name
  28. # @param class_name str : The class name
  29. # @return str
  30. def object_collection_name(class_name):
  31. return ("%s%s" % (collection_prefix['object'], class_name)).lower()
  32. ## @brief converts the query filters into MongoDB filters
  33. # @param query_filters list : list of query_filters as tuples or dicts
  34. # @param as_list bool : defines if the output will be a list (default: False)
  35. # @return dict|list
  36. # @todo refactor this function by adding a return_type argument (default= dict) which can be a dict or a list, then delete the convert_filter_list function
  37. def parse_query_filters(query_filters, as_list=False):
  38. parsed_filters = dict() if not as_list else list()
  39. for query_filter in query_filters:
  40. if isinstance(query_filter, tuple):
  41. if as_list:
  42. parsed_filters.append(convert_filter(query_filter))
  43. else:
  44. parsed_filters.update(convert_filter(query_filter))
  45. elif isinstance(query_filter, dict):
  46. query_item = list(query_filter.items())[0]
  47. key = LODEL_OPERATORS_MAP[query_item[0]]
  48. if as_list:
  49. parsed_filters.append({key: parse_query_filters(query_item[1], as_list=True)})
  50. else:
  51. parsed_filters.update({key: parse_query_filters(query_item[1], as_list=True)})
  52. else:
  53. # TODO Add an exception management here in case the filter is neither a tuple nor a dict
  54. pass
  55. return parsed_filters
  56. ## @brief converts a Lodel query filter into a MongoDB filter
  57. # @param filter_params tuple : (FIELD, OPERATOR, VALUE) representing the query filter to convert
  58. # @return dict : {KEY: {OPERATOR:VALUE}}
  59. # @todo Add an error management for the operator mismatch
  60. # @todo Add the checks for the type of values authorized in certain mongodb operators, such "$in" for example which takes a list
  61. def convert_filter(filter_params):
  62. key, operator, value = filter_params
  63. if operator not in ('like', 'not like'):
  64. converted_operator = LODEL_OPERATORS_MAP[operator]['name']
  65. converted_filter = {key: {converted_operator: value}}
  66. else:
  67. converted_filter = convert_like_filter(filter_params)
  68. return converted_filter
  69. ## @brief Returns a list of sorting options
  70. # @param query_filters_order list
  71. # @return list
  72. def parse_query_order(query_filters_order):
  73. ordering = list()
  74. for query_filter_order in query_filters_order:
  75. field, direction = query_filter_order
  76. ordering.append((field, LODEL_SORT_OPERATORS_MAP[direction]))
  77. return ordering
  78. ## @brief Converts "like" and "not like" filters into MongotDb filters
  79. # @param like_filter tuple
  80. # @return dict
  81. def convert_like_filter(like_filter):
  82. key, operator, value = like_filter
  83. is_starting_with = value.endswith('*')
  84. is_ending_with = value.startswith('*')
  85. if is_starting_with and not is_ending_with:
  86. regex_pattern = value.replace('*', '^')
  87. elif is_ending_with and not is_starting_with:
  88. regex_pattern = value.replace('*', '$')
  89. elif is_starting_with and is_ending_with:
  90. regex_pattern = '%s' % value
  91. else:
  92. regex_pattern = '^%s$' % value
  93. regex_condition = {'$regex': regex_pattern, '$options': 'i'}
  94. converted_filter = {key: regex_condition}
  95. if operator.startswith('not'):
  96. converted_filter = {key: {'$not': regex_condition}}
  97. return converted_filter