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.
 
 
 
 
 
 

185 lines
5.6 KiB

  1. # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
  2. # License: MIT. See LICENSE
  3. import frappe, json
  4. from frappe.model.document import Document
  5. from frappe.desk.notifications import (delete_notification_count_for,
  6. clear_notifications)
  7. common_default_keys = ["__default", "__global"]
  8. doctype_map_keys = ('energy_point_rule_map', 'assignment_rule_map',
  9. 'milestone_tracker_map', 'event_consumer_document_type_map')
  10. bench_cache_keys = ('assets_json',)
  11. global_cache_keys = ("app_hooks", "installed_apps", 'all_apps',
  12. "app_modules", "module_app", "system_settings",
  13. 'scheduler_events', 'time_zone', 'webhooks', 'active_domains',
  14. 'active_modules', 'assignment_rule', 'server_script_map', 'wkhtmltopdf_version',
  15. 'domain_restricted_doctypes', 'domain_restricted_pages', 'information_schema:counts',
  16. 'sitemap_routes', 'db_tables', 'server_script_autocompletion_items') + doctype_map_keys
  17. user_cache_keys = ("bootinfo", "user_recent", "roles", "user_doc", "lang",
  18. "defaults", "user_permissions", "home_page", "linked_with",
  19. "desktop_icons", 'portal_menu_items', 'user_perm_can_read',
  20. "has_role:Page", "has_role:Report", "desk_sidebar_items")
  21. doctype_cache_keys = ("meta", "form_meta", "table_columns", "last_modified",
  22. "linked_doctypes", 'notifications', 'workflow' ,
  23. 'data_import_column_header_map') + doctype_map_keys
  24. def clear_user_cache(user=None):
  25. cache = frappe.cache()
  26. # this will automatically reload the global cache
  27. # so it is important to clear this first
  28. clear_notifications(user)
  29. if user:
  30. for name in user_cache_keys:
  31. cache.hdel(name, user)
  32. cache.delete_keys("user:" + user)
  33. clear_defaults_cache(user)
  34. else:
  35. for name in user_cache_keys:
  36. cache.delete_key(name)
  37. clear_defaults_cache()
  38. clear_global_cache()
  39. def clear_domain_cache(user=None):
  40. cache = frappe.cache()
  41. domain_cache_keys = ('domain_restricted_doctypes', 'domain_restricted_pages')
  42. cache.delete_value(domain_cache_keys)
  43. def clear_global_cache():
  44. from frappe.website.utils import clear_website_cache
  45. clear_doctype_cache()
  46. clear_website_cache()
  47. frappe.cache().delete_value(global_cache_keys)
  48. frappe.cache().delete_value(bench_cache_keys)
  49. frappe.setup_module_map()
  50. def clear_defaults_cache(user=None):
  51. if user:
  52. for p in ([user] + common_default_keys):
  53. frappe.cache().hdel("defaults", p)
  54. elif frappe.flags.in_install!="frappe":
  55. frappe.cache().delete_key("defaults")
  56. def clear_doctype_cache(doctype=None):
  57. clear_controller_cache(doctype)
  58. cache = frappe.cache()
  59. if getattr(frappe.local, 'meta_cache') and (doctype in frappe.local.meta_cache):
  60. del frappe.local.meta_cache[doctype]
  61. for key in ('is_table', 'doctype_modules', 'document_cache'):
  62. cache.delete_value(key)
  63. frappe.local.document_cache = {}
  64. def clear_single(dt):
  65. for name in doctype_cache_keys:
  66. cache.hdel(name, dt)
  67. if doctype:
  68. clear_single(doctype)
  69. # clear all parent doctypes
  70. for dt in frappe.db.get_all('DocField', 'parent',
  71. dict(fieldtype=['in', frappe.model.table_fields], options=doctype)):
  72. clear_single(dt.parent)
  73. # clear all notifications
  74. delete_notification_count_for(doctype)
  75. else:
  76. # clear all
  77. for name in doctype_cache_keys:
  78. cache.delete_value(name)
  79. def clear_controller_cache(doctype=None):
  80. if not doctype:
  81. del frappe.controllers
  82. frappe.controllers = {}
  83. return
  84. for site_controllers in frappe.controllers.values():
  85. site_controllers.pop(doctype, None)
  86. def get_doctype_map(doctype, name, filters=None, order_by=None):
  87. cache = frappe.cache()
  88. cache_key = frappe.scrub(doctype) + '_map'
  89. doctype_map = cache.hget(cache_key, name)
  90. if doctype_map is not None:
  91. # cached, return
  92. items = json.loads(doctype_map)
  93. else:
  94. # non cached, build cache
  95. try:
  96. items = frappe.get_all(doctype, filters=filters, order_by = order_by)
  97. cache.hset(cache_key, name, json.dumps(items))
  98. except frappe.db.TableMissingError:
  99. # executed from inside patch, ignore
  100. items = []
  101. return items
  102. def clear_doctype_map(doctype, name):
  103. frappe.cache().hdel(frappe.scrub(doctype) + '_map', name)
  104. def build_table_count_cache():
  105. if (frappe.flags.in_patch
  106. or frappe.flags.in_install
  107. or frappe.flags.in_migrate
  108. or frappe.flags.in_import
  109. or frappe.flags.in_setup_wizard):
  110. return
  111. _cache = frappe.cache()
  112. table_name = frappe.qb.Field("table_name").as_("name")
  113. table_rows = frappe.qb.Field("table_rows").as_("count")
  114. information_schema = frappe.qb.Schema("information_schema")
  115. data = (
  116. frappe.qb.from_(information_schema.tables).select(table_name, table_rows)
  117. ).run(as_dict=True)
  118. counts = {d.get('name').lstrip('tab'): d.get('count', None) for d in data}
  119. _cache.set_value("information_schema:counts", counts)
  120. return counts
  121. def build_domain_restriced_doctype_cache(*args, **kwargs):
  122. if (frappe.flags.in_patch
  123. or frappe.flags.in_install
  124. or frappe.flags.in_migrate
  125. or frappe.flags.in_import
  126. or frappe.flags.in_setup_wizard):
  127. return
  128. _cache = frappe.cache()
  129. active_domains = frappe.get_active_domains()
  130. doctypes = frappe.get_all("DocType", filters={'restrict_to_domain': ('IN', active_domains)})
  131. doctypes = [doc.name for doc in doctypes]
  132. _cache.set_value("domain_restricted_doctypes", doctypes)
  133. return doctypes
  134. def build_domain_restriced_page_cache(*args, **kwargs):
  135. if (frappe.flags.in_patch
  136. or frappe.flags.in_install
  137. or frappe.flags.in_migrate
  138. or frappe.flags.in_import
  139. or frappe.flags.in_setup_wizard):
  140. return
  141. _cache = frappe.cache()
  142. active_domains = frappe.get_active_domains()
  143. pages = frappe.get_all("Page", filters={'restrict_to_domain': ('IN', active_domains)})
  144. pages = [page.name for page in pages]
  145. _cache.set_value("domain_restricted_pages", pages)
  146. return pages