From eb9d2bcd649b6dba7e764ae5f34a61c8b0c51d9c Mon Sep 17 00:00:00 2001 From: saxenabhishek Date: Thu, 15 Jul 2021 01:21:31 +0530 Subject: [PATCH] feat: Query builder --- frappe/__init__.py | 4 +++ frappe/query_builder/__init__.py | 1 + frappe/query_builder/qb.py | 53 ++++++++++++++++++++++++++++++++ requirements.txt | 1 + 4 files changed, 59 insertions(+) create mode 100644 frappe/query_builder/__init__.py create mode 100644 frappe/query_builder/qb.py diff --git a/frappe/__init__.py b/frappe/__init__.py index 1c978945c7..39e21efb9e 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -28,6 +28,8 @@ from .exceptions import * from .utils.jinja import (get_jenv, get_template, render_template, get_email_from_template, get_jloader) from .utils.lazy_loader import lazy_import +from frappe.query_builder import query_builder + # Lazy imports faker = lazy_import('faker') @@ -118,6 +120,7 @@ def set_user_lang(user, user_language=None): # local-globals db = local("db") +qb = local("qb") conf = local("conf") form = form_dict = local("form_dict") request = local("request") @@ -202,6 +205,7 @@ def init(site, sites_path=None, new_site=False): local.form_dict = _dict() local.session = _dict() local.dev_server = _dev_server + local.qb = query_builder(local.conf.db_type) setup_module_map() diff --git a/frappe/query_builder/__init__.py b/frappe/query_builder/__init__.py new file mode 100644 index 0000000000..da1748beec --- /dev/null +++ b/frappe/query_builder/__init__.py @@ -0,0 +1 @@ +from frappe.query_builder.qb import qb as query_builder diff --git a/frappe/query_builder/qb.py b/frappe/query_builder/qb.py new file mode 100644 index 0000000000..6fa54661e8 --- /dev/null +++ b/frappe/query_builder/qb.py @@ -0,0 +1,53 @@ +from pypika import MySQLQuery, Order, PostgreSQLQuery +from pypika import functions as fn +from pypika import terms +from pypika.queries import Schema, Table + +def qb(db_type): + if not db_type: + db_type = "mariadb" + selecter = {"mariadb": MariaDB, "postgres": Postgres} + return selecter[db_type] + +class common: + fn = fn + terms = terms + desc = Order.desc + Schema = Schema + +class MariaDB(MySQLQuery,common): + Field = terms.Field + + 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) + +class Postgres(PostgreSQLQuery,common): + postgres_field = {"table_name": "relname", "table_rows": "n_tup_ins"} + information_schema_translation = {"tables": "pg_stat_all_tables"} + + def __init__(self) -> None: + super().__init__() + + @classmethod + def Field(cls, fieldName, *args, **kwargs): + if fieldName in cls.postgres_field: + fieldName = cls.postgres_field[fieldName] + return terms.Field(fieldName, *args, **kwargs) + + @classmethod + def from_(cls, class_name, *args, **kwargs): + if isinstance(class_name, Table): + if class_name._schema: + if class_name._schema._name == "information_schema": + class_name = cls.information_schema_translation[class_name._table_name] + + elif isinstance(class_name, str): + class_name = "tab" + class_name + + return super().from_(class_name, *args, **kwargs) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 0791f01b27..51327953d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -49,6 +49,7 @@ pyngrok~=5.0.5 pyOpenSSL~=20.0.1 pyotp~=2.6.0 PyPDF2~=1.26.0 +PyPika~=0.48.6 pypng~=0.0.20 PyQRCode~=1.2.1 python-dateutil~=2.8.1