seitime-frappe/frappe/cache_manager.py
Gavin D'souza 3446026555 chore: Update header: license.txt => LICENSE
The license.txt file has been replaced with LICENSE for quite a while
now. INAL but it didn't seem accurate to say "hey, checkout license.txt
although there's no such file". Apart from this, there were
inconsistencies in the headers altogether...this change brings
consistency.
2021-09-03 12:02:59 +05:30

184 lines
5.6 KiB
Python

# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
import frappe, json
from frappe.model.document import Document
from frappe.desk.notifications import (delete_notification_count_for,
clear_notifications)
common_default_keys = ["__default", "__global"]
doctype_map_keys = ('energy_point_rule_map', 'assignment_rule_map',
'milestone_tracker_map', 'event_consumer_document_type_map')
bench_cache_keys = ('assets_json',)
global_cache_keys = ("app_hooks", "installed_apps", 'all_apps',
"app_modules", "module_app", "system_settings",
'scheduler_events', 'time_zone', 'webhooks', 'active_domains',
'active_modules', 'assignment_rule', 'server_script_map', 'wkhtmltopdf_version',
'domain_restricted_doctypes', 'domain_restricted_pages', 'information_schema:counts',
'sitemap_routes', 'db_tables', 'server_script_autocompletion_items') + doctype_map_keys
user_cache_keys = ("bootinfo", "user_recent", "roles", "user_doc", "lang",
"defaults", "user_permissions", "home_page", "linked_with",
"desktop_icons", 'portal_menu_items', 'user_perm_can_read',
"has_role:Page", "has_role:Report", "desk_sidebar_items")
doctype_cache_keys = ("meta", "form_meta", "table_columns", "last_modified",
"linked_doctypes", 'notifications', 'workflow' ,
'data_import_column_header_map') + doctype_map_keys
def clear_user_cache(user=None):
cache = frappe.cache()
# this will automatically reload the global cache
# so it is important to clear this first
clear_notifications(user)
if user:
for name in user_cache_keys:
cache.hdel(name, user)
cache.delete_keys("user:" + user)
clear_defaults_cache(user)
else:
for name in user_cache_keys:
cache.delete_key(name)
clear_defaults_cache()
clear_global_cache()
def clear_domain_cache(user=None):
cache = frappe.cache()
domain_cache_keys = ('domain_restricted_doctypes', 'domain_restricted_pages')
cache.delete_value(domain_cache_keys)
def clear_global_cache():
from frappe.website.utils import clear_website_cache
clear_doctype_cache()
clear_website_cache()
frappe.cache().delete_value(global_cache_keys)
frappe.cache().delete_value(bench_cache_keys)
frappe.setup_module_map()
def clear_defaults_cache(user=None):
if user:
for p in ([user] + common_default_keys):
frappe.cache().hdel("defaults", p)
elif frappe.flags.in_install!="frappe":
frappe.cache().delete_key("defaults")
def clear_doctype_cache(doctype=None):
clear_controller_cache(doctype)
cache = frappe.cache()
if getattr(frappe.local, 'meta_cache') and (doctype in frappe.local.meta_cache):
del frappe.local.meta_cache[doctype]
for key in ('is_table', 'doctype_modules', 'document_cache'):
cache.delete_value(key)
frappe.local.document_cache = {}
def clear_single(dt):
for name in doctype_cache_keys:
cache.hdel(name, dt)
if doctype:
clear_single(doctype)
# clear all parent doctypes
for dt in frappe.db.get_all('DocField', 'parent',
dict(fieldtype=['in', frappe.model.table_fields], options=doctype)):
clear_single(dt.parent)
# clear all notifications
delete_notification_count_for(doctype)
else:
# clear all
for name in doctype_cache_keys:
cache.delete_value(name)
def clear_controller_cache(doctype=None):
if not doctype:
del frappe.controllers
frappe.controllers = {}
return
for site_controllers in frappe.controllers.values():
site_controllers.pop(doctype, None)
def get_doctype_map(doctype, name, filters=None, order_by=None):
cache = frappe.cache()
cache_key = frappe.scrub(doctype) + '_map'
doctype_map = cache.hget(cache_key, name)
if doctype_map is not None:
# cached, return
items = json.loads(doctype_map)
else:
# non cached, build cache
try:
items = frappe.get_all(doctype, filters=filters, order_by = order_by)
cache.hset(cache_key, name, json.dumps(items))
except frappe.db.TableMissingError:
# executed from inside patch, ignore
items = []
return items
def clear_doctype_map(doctype, name):
frappe.cache().hdel(frappe.scrub(doctype) + '_map', name)
def build_table_count_cache():
if (frappe.flags.in_patch
or frappe.flags.in_install
or frappe.flags.in_migrate
or frappe.flags.in_import
or frappe.flags.in_setup_wizard):
return
_cache = frappe.cache()
table_name = frappe.qb.Field("table_name").as_("name")
table_rows = frappe.qb.Field("table_rows").as_("count")
information_schema = frappe.qb.Schema("information_schema")
data = (
frappe.qb.from_(information_schema.tables).select(table_name, table_rows)
).run(as_dict=True)
counts = {d.get('name').lstrip('tab'): d.get('count', None) for d in data}
_cache.set_value("information_schema:counts", counts)
return counts
def build_domain_restriced_doctype_cache(*args, **kwargs):
if (frappe.flags.in_patch
or frappe.flags.in_install
or frappe.flags.in_migrate
or frappe.flags.in_import
or frappe.flags.in_setup_wizard):
return
_cache = frappe.cache()
active_domains = frappe.get_active_domains()
doctypes = frappe.get_all("DocType", filters={'restrict_to_domain': ('IN', active_domains)})
doctypes = [doc.name for doc in doctypes]
_cache.set_value("domain_restricted_doctypes", doctypes)
return doctypes
def build_domain_restriced_page_cache(*args, **kwargs):
if (frappe.flags.in_patch
or frappe.flags.in_install
or frappe.flags.in_migrate
or frappe.flags.in_import
or frappe.flags.in_setup_wizard):
return
_cache = frappe.cache()
active_domains = frappe.get_active_domains()
pages = frappe.get_all("Page", filters={'restrict_to_domain': ('IN', active_domains)})
pages = [page.name for page in pages]
_cache.set_value("domain_restricted_pages", pages)
return pages