Merge pull request #22017 from GursheenK/implement-like-in-compare-util
feat: implement like in compare util
This commit is contained in:
commit
cbe816347e
4 changed files with 41 additions and 22 deletions
|
|
@ -4,7 +4,7 @@
|
|||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.recorder import get as get_recorder_data
|
||||
from frappe.utils import cint, compare, make_filter_dict
|
||||
from frappe.utils import cint, evaluate_filters, make_filter_dict
|
||||
|
||||
|
||||
class Recorder(Document):
|
||||
|
|
@ -47,7 +47,7 @@ class Recorder(Document):
|
|||
order_by_statment = order_by_statment.split(".")[1]
|
||||
|
||||
if " " in order_by_statment:
|
||||
sort_key, sort_order = order_by_statment.split(" ")
|
||||
sort_key, sort_order = order_by_statment.split(" ", 1)
|
||||
else:
|
||||
sort_key = order_by_statment
|
||||
sort_order = "desc"
|
||||
|
|
@ -63,9 +63,9 @@ class Recorder(Document):
|
|||
|
||||
@staticmethod
|
||||
def get_filtered_requests(args):
|
||||
filters = make_filter_dict(args.get("filters"))
|
||||
filters = args.get("filters")
|
||||
requests = [serialize_request(request) for request in get_recorder_data()]
|
||||
return [req for req in requests if _evaluate_filters(req, filters)]
|
||||
return [req for req in requests if evaluate_filters(req, filters)]
|
||||
|
||||
@staticmethod
|
||||
def get_stats(args):
|
||||
|
|
@ -100,20 +100,3 @@ def serialize_request(request):
|
|||
)
|
||||
|
||||
return request
|
||||
|
||||
|
||||
def _evaluate_filters(row, filters) -> bool:
|
||||
for field in filters:
|
||||
value = row[field]
|
||||
operand = filters[field][1]
|
||||
operator = filters[field][0]
|
||||
|
||||
if operator == "like":
|
||||
operator = "in" # python equivalent.
|
||||
operand = operand.strip("%")
|
||||
# Swap because like is "reverse IN"
|
||||
value, operand = operand, value
|
||||
|
||||
if not compare(value, operator, operand):
|
||||
return False
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ class TestRecorder(FrappeTestCase):
|
|||
def setUp(self):
|
||||
self.start_recoder()
|
||||
|
||||
def tearDown(self) -> None:
|
||||
frappe.recorder.stop()
|
||||
|
||||
def start_recoder(self):
|
||||
frappe.recorder.stop()
|
||||
frappe.recorder.delete()
|
||||
|
|
|
|||
|
|
@ -173,6 +173,23 @@ class TestFilters(FrappeTestCase):
|
|||
)
|
||||
)
|
||||
|
||||
def test_like_not_like(self):
|
||||
doc = {"doctype": "User", "username": "test_abc", "prefix": "startswith", "suffix": "endswith"}
|
||||
|
||||
test_cases = [
|
||||
([["username", "like", "test"]], True),
|
||||
([["username", "like", "user1"]], False),
|
||||
([["username", "not like", "test"]], False),
|
||||
([["username", "not like", "user1"]], True),
|
||||
([["prefix", "like", "start%"]], True),
|
||||
([["prefix", "not like", "end%"]], True),
|
||||
([["suffix", "like", "%with"]], True),
|
||||
([["suffix", "not like", "%end"]], True),
|
||||
]
|
||||
|
||||
for filter, expected_result in test_cases:
|
||||
self.assertEqual(evaluate_filters(doc, filter), expected_result)
|
||||
|
||||
|
||||
class TestMoney(FrappeTestCase):
|
||||
def test_money_in_words(self):
|
||||
|
|
|
|||
|
|
@ -1692,6 +1692,20 @@ def get_url_to_report_with_filters(name, filters, report_type=None, doctype=None
|
|||
return get_url(uri=f"/app/query-report/{quoted(name)}?{filters}")
|
||||
|
||||
|
||||
def sql_like(value: str, pattern: str) -> bool:
|
||||
if not isinstance(pattern, str) and isinstance(value, str):
|
||||
return False
|
||||
if pattern.startswith("%") and pattern.endswith("%"):
|
||||
return pattern.strip("%") in value
|
||||
elif pattern.startswith("%"):
|
||||
return value.endswith(pattern.lstrip("%"))
|
||||
elif pattern.endswith("%"):
|
||||
return value.startswith(pattern.rstrip("%"))
|
||||
else:
|
||||
# assume default as wrapped in '%'
|
||||
return pattern in value
|
||||
|
||||
|
||||
operator_map = {
|
||||
# startswith
|
||||
"^": lambda a, b: (a or "").startswith(b),
|
||||
|
|
@ -1707,6 +1721,8 @@ operator_map = {
|
|||
"<=": operator.le,
|
||||
"not None": lambda a, b: a is not None,
|
||||
"None": lambda a, b: a is None,
|
||||
"like": sql_like,
|
||||
"not like": lambda a, b: not sql_like(a, b),
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1812,7 +1828,7 @@ def get_filter(doctype: str, f: dict | list | tuple, filters_config=None) -> "fr
|
|||
break
|
||||
|
||||
try:
|
||||
df = frappe.get_meta(f.doctype).get_field(f.fieldname)
|
||||
df = frappe.get_meta(f.doctype).get_field(f.fieldname) if f.doctype else None
|
||||
except frappe.exceptions.DoesNotExistError:
|
||||
df = None
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue