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.
 
 
 
 
 
 

246 line
5.7 KiB

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