diff --git a/frappe/database.py b/frappe/database.py index 9f42e8e131..28cb57efa7 100644 --- a/frappe/database.py +++ b/frappe/database.py @@ -39,6 +39,7 @@ class Database: self.auto_commit_on_many_writes = 0 self.password = password or frappe.conf.db_password + self.value_cache = {} def get_db_login(self, ac_name): return ac_name @@ -128,7 +129,6 @@ class Database: frappe.log("with values:") frappe.log(values) frappe.log(">>>>") - self._cursor.execute(query, values) else: @@ -361,11 +361,11 @@ class Database: return " and ".join(conditions), values - def get(self, doctype, filters=None, as_dict=True): + def get(self, doctype, filters=None, as_dict=True, cache=False): """Returns `get_value` with fieldname='*'""" - return self.get_value(doctype, filters, "*", as_dict=as_dict) + return self.get_value(doctype, filters, "*", as_dict=as_dict, cache=cache) - def get_value(self, doctype, filters=None, fieldname="name", ignore=None, as_dict=False, debug=False): + def get_value(self, doctype, filters=None, fieldname="name", ignore=None, as_dict=False, debug=False, cache=False): """Returns a document property or list of properties. :param doctype: DocType name. @@ -390,11 +390,12 @@ class Database: frappe.db.get_value("System Settings", None, "date_format") """ - ret = self.get_values(doctype, filters, fieldname, ignore, as_dict, debug) + ret = self.get_values(doctype, filters, fieldname, ignore, as_dict, debug, cache=cache) return ((len(ret[0]) > 1 or as_dict) and ret[0] or ret[0][0]) if ret else None - def get_values(self, doctype, filters=None, fieldname="name", ignore=None, as_dict=False, debug=False, order_by=None, update=None): + def get_values(self, doctype, filters=None, fieldname="name", ignore=None, as_dict=False, + debug=False, order_by=None, update=None, cache=False): """Returns multiple document properties. :param doctype: DocType name. @@ -412,31 +413,41 @@ class Database: # return last login of **User** `test@example.com` user = frappe.db.get_values("User", "test@example.com", "*")[0] """ + out = None + if cache and isinstance(filters, basestring) and \ + (doctype, filters, fieldname) in self.value_cache: + return self.value_cache[(doctype, filters, fieldname)] if isinstance(filters, list): - return self._get_value_for_many_names(doctype, filters, fieldname, debug=debug) + out = self._get_value_for_many_names(doctype, filters, fieldname, debug=debug) - fields = fieldname - if fieldname!="*": - if isinstance(fieldname, basestring): - fields = [fieldname] + else: + fields = fieldname + if fieldname!="*": + if isinstance(fieldname, basestring): + fields = [fieldname] + else: + fields = fieldname + + if (filters is not None) and (filters!=doctype or doctype=="DocType"): + try: + out = self._get_values_from_table(fields, filters, doctype, as_dict, debug, order_by, update) + except Exception, e: + if ignore and e.args[0] in (1146, 1054): + # table or column not found, return None + out = None + elif (not ignore) and e.args[0]==1146: + # table not found, look in singles + out = self.get_values_from_single(fields, filters, doctype, as_dict, debug, update) + else: + raise else: - fields = fieldname + out = self.get_values_from_single(fields, filters, doctype, as_dict, debug, update) - if (filters is not None) and (filters!=doctype or doctype=="DocType"): - try: - return self._get_values_from_table(fields, filters, doctype, as_dict, debug, order_by, update) - except Exception, e: - if ignore and e.args[0] in (1146, 1054): - # table or column not found, return None - return None - elif (not ignore) and e.args[0]==1146: - # table not found, look in singles - pass - else: - raise + if cache and isinstance(filters, basestring): + self.value_cache[(doctype, filters, fieldname)] = out - return self.get_values_from_single(fields, filters, doctype, as_dict, debug, update) + return out def get_values_from_single(self, fields, filters, doctype, as_dict=False, debug=False, update=None): """Get values from `tabSingles` (Single DocTypes) (internal). diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index 8ccb4440bb..95965b6c57 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -357,7 +357,7 @@ class BaseDocument(object): frappe.throw(_("{0} must be set first").format(self.meta.get_label(df.options))) # MySQL is case insensitive. Preserve case of the original docname in the Link Field. - value = frappe.db.get_value(doctype, docname) + value = frappe.db.get_value(doctype, docname, "name", cache=True) setattr(self, df.fieldname, value) if not value: diff --git a/frappe/model/document.py b/frappe/model/document.py index eb019096b2..76cee18335 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _, msgprint -from frappe.utils import flt, cint, cstr, now, get_datetime_str +from frappe.utils import flt, cstr, now, get_datetime_str from frappe.model.base_document import BaseDocument, get_controller from frappe.model.naming import set_new_name from werkzeug.exceptions import NotFound, Forbidden @@ -364,11 +364,13 @@ class Document(BaseDocument): if cstr(modified) and cstr(modified) != cstr(self._original_modified): conflict = True else: - tmp = frappe.db.get_value(self.doctype, self.name, - ["modified", "docstatus"], as_dict=True) + tmp = frappe.db.sql("""select modified, docstatus from `tab{0}` + where name = %s for update""".format(self.doctype), self.name, as_dict=True) if not tmp: frappe.throw(_("Record does not exist")) + else: + tmp = tmp[0] modified = cstr(tmp.modified) diff --git a/frappe/model/meta.py b/frappe/model/meta.py index 6d6f289055..34050d0afe 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -282,7 +282,7 @@ def get_field_precision(df, doc=None, currency=None): currency = frappe.db.get_default("currency") if currency: - number_format = frappe.db.get_value("Currency", currency, "number_format") + number_format = frappe.db.get_value("Currency", currency, "number_format", cache=True) if not number_format: number_format = frappe.db.get_default("number_format") or "#,###.##" diff --git a/frappe/templates/includes/contact.js b/frappe/templates/includes/contact.js index 1d5adaceae..869b4dce60 100644 --- a/frappe/templates/includes/contact.js +++ b/frappe/templates/includes/contact.js @@ -3,7 +3,7 @@ frappe.ready(function() { - $('.btn-send').click(function() { + $('.btn-send').off("click").on("click", function() { var email = $('[name="email"]').val(); var message = $('[name="message"]').val(); diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 27d83abce1..00593aa9b7 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -301,7 +301,7 @@ def fmt_money(amount, precision=None, currency=None): """ number_format = None if currency: - number_format = frappe.db.get_value("Currency", currency, "number_format") + number_format = frappe.db.get_value("Currency", currency, "number_format", cache=True) if not number_format: number_format = frappe.db.get_default("number_format") or "#,###.##" @@ -387,7 +387,7 @@ def money_in_words(number, main_currency = None, fraction_currency=None): if len(fraction)==1: fraction += '0' - number_format = frappe.db.get_value("Currency", main_currency, "number_format") or \ + number_format = frappe.db.get_value("Currency", main_currency, "number_format", cache=True) or \ frappe.db.get_default("number_format") or "#,###.##" in_million = True