From 2f7c78b266a09e27beaf418b42f47249a7e46170 Mon Sep 17 00:00:00 2001 From: saxenabhishek Date: Thu, 15 Jul 2021 02:00:50 +0530 Subject: [PATCH] refactor: qb in patch v12 set_correct_assign_value_in_docs --- .../v12_0/set_correct_assign_value_in_docs.py | 32 +++++++++---------- frappe/query_builder/custom_functions.py | 12 +++++++ frappe/query_builder/qb.py | 21 ++++++++---- 3 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 frappe/query_builder/custom_functions.py diff --git a/frappe/patches/v12_0/set_correct_assign_value_in_docs.py b/frappe/patches/v12_0/set_correct_assign_value_in_docs.py index 65a635c170..72e71c8314 100644 --- a/frappe/patches/v12_0/set_correct_assign_value_in_docs.py +++ b/frappe/patches/v12_0/set_correct_assign_value_in_docs.py @@ -1,25 +1,23 @@ import frappe + def execute(): - frappe.reload_doc('desk', 'doctype', 'todo') + frappe.reload_doc("desk", "doctype", "todo") - query = ''' - SELECT - name, reference_type, reference_name, {} as assignees - FROM - `tabToDo` - WHERE - COALESCE(reference_type, '') != '' AND - COALESCE(reference_name, '') != '' AND - status != 'Cancelled' - GROUP BY - reference_type, reference_name - ''' + ToDo = frappe.qb.Table("ToDo") + assignees = frappe.qb.GROUP_CONCAT("owner").distinct().as_("assignees") - assignments = frappe.db.multisql({ - 'mariadb': query.format('GROUP_CONCAT(DISTINCT `owner`)'), - 'postgres': query.format('STRING_AGG(DISTINCT "owner", ",")') - }, as_dict=True) + q = ( + frappe.qb.from_(ToDo) + .select(ToDo.name, ToDo.reference_type, assignees) + .where(frappe.qb.fn.Coalesce(ToDo.reference_type, "") != "") + .where(frappe.qb.fn.Coalesce(ToDo.reference_name, "") != "") + .where(ToDo.status != "Cancelled") + .groupby(ToDo.reference_type, ToDo.reference_name) + .get_sql() + ) + + assignments = frappe.db.sql(q, as_dict=True) for doc in assignments: assignments = doc.assignees.split(',') diff --git a/frappe/query_builder/custom_functions.py b/frappe/query_builder/custom_functions.py new file mode 100644 index 0000000000..446a4df2d2 --- /dev/null +++ b/frappe/query_builder/custom_functions.py @@ -0,0 +1,12 @@ +from pypika import functions as fn + + + +class GROUP_CONCAT(fn.DistinctOptionFunction): + def __init__(self, col, alias=None): + super(GROUP_CONCAT, self).__init__("GROUP_CONCAT", col, alias=alias) + + +class STRING_AGG(fn.DistinctOptionFunction): + def __init__(self, col, val=",", alias=None): + super(STRING_AGG, self).__init__("STRING_AGG", col, val, alias=alias) diff --git a/frappe/query_builder/qb.py b/frappe/query_builder/qb.py index ddf514ab2c..fb92eed56b 100644 --- a/frappe/query_builder/qb.py +++ b/frappe/query_builder/qb.py @@ -2,6 +2,7 @@ from pypika import MySQLQuery, Order, PostgreSQLQuery from pypika import functions as fn from pypika import terms from pypika.queries import Schema, Table +from .custom_functions import GROUP_CONCAT, STRING_AGG def qb(db_type): if not db_type: @@ -14,19 +15,25 @@ class common: terms = terms desc = Order.desc Schema = Schema + @staticmethod + def Table(classname:str, *args, **kwargs): + if not classname.startswith("__"): + classname = "tab" + classname + return Table(classname, *args, **kwargs) -class MariaDB(MySQLQuery,common): +class MariaDB(common, MySQLQuery,): Field = terms.Field + GROUP_CONCAT = GROUP_CONCAT def __init__(self) -> None: super().__init__() - + @classmethod def from_(cls, class_name, *args, **kwargs): if isinstance(class_name,str): class_name = "tab"+class_name return super().from_(class_name, *args, **kwargs) - + @staticmethod def rename_table(old_name, new_name): return f"RENAME TABLE `tab{old_name}` TO `tab{new_name}`" @@ -39,9 +46,11 @@ class MariaDB(MySQLQuery,common): def change_table_type(tb, col, type): return f"ALTER TABLE `{tb}` MODIFY `{col}` {type} NOT NULL" -class Postgres(PostgreSQLQuery,common): + +class Postgres(common, PostgreSQLQuery,): postgres_field = {"table_name": "relname", "table_rows": "n_tup_ins"} information_schema_translation = {"tables": "pg_stat_all_tables"} + GROUP_CONCAT = STRING_AGG def __init__(self) -> None: super().__init__() @@ -63,11 +72,11 @@ class Postgres(PostgreSQLQuery,common): class_name = "tab" + class_name return super().from_(class_name, *args, **kwargs) - + @staticmethod def rename_table(old_name, new_name): return f"ALTER TABLE `tab{old_name}` RENAME TO `tab{new_name}`" - + @staticmethod def DESC(dt): return f"SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = 'tab{dt}'"