diff --git a/frappe/database.py b/frappe/database.py index bb3085c038..d5c8d77fee 100644 --- a/frappe/database.py +++ b/frappe/database.py @@ -81,6 +81,9 @@ class Database: # in transaction validations self.check_transaction_status(query) + # prevent multiple queries in one + self.prevent_multiple_queries(query) + # autocommit if auto_commit: self.commit() @@ -559,3 +562,23 @@ class Database: if isinstance(s, unicode): s = (s or "").encode("utf-8") return unicode(MySQLdb.escape_string(s), "utf-8") + + def prevent_multiple_queries(self, query): + if frappe.flags.in_install_db or frappe.flags.in_install: + return + + query_lower = query.lower().split(";") + + if len(query_lower) > 1: + for q in query_lower[1:]: + if q.strip() and q.strip().split()[0] in ( + "update", + "truncate", + "alter", + "drop", + "create", + "begin", + "start transaction", + "commit" + ): + frappe.throw(_("Cannot have more than one SQL statement in a query."), frappe.SQLError) diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index be0e5fcca6..ce8b9f3492 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -19,3 +19,7 @@ class TestDB(unittest.TestCase): def test_escape(self): frappe.db.escape("香港濟生堂製藥有限公司 - IT".encode("utf-8")) + + def test_multiple_queries(self): + # implicit commit + self.assertRaises(frappe.SQLError, frappe.db.sql, """select name from `tabUser`; truncate `tabBulk Email`""")