pierrejeambrun commented on code in PR #44516:
URL: https://github.com/apache/airflow/pull/44516#discussion_r1878471399


##########
airflow/api_fastapi/common/parameters.py:
##########
@@ -146,6 +147,127 @@ def depends_search(value: str | None = 
Query(alias=pattern_name, default=None))
     return depends_search
 
 
+class SearchPatternEnum(Enum):

Review Comment:
   Maybe we should reuse `FilterOptionEnum` and rename it to a more `generic` 
form. maybe move it to the DB package.
   
   DB operations supported by the query parameters and the one from advanced 
search will basically be very close. (and this will avoid duplication). 
   
   As we do for `states` `task_states` `dag_run_states`, etc.. we can split 
`FilterOperator` `AdvancedSearchOperator`, etc...



##########
airflow/api_fastapi/common/parameters.py:
##########
@@ -146,6 +147,127 @@ def depends_search(value: str | None = 
Query(alias=pattern_name, default=None))
     return depends_search
 
 
+class SearchPatternEnum(Enum):
+    """
+    Enum representing the types of search patterns supported.
+
+    - STARTS_WITH: Matches strings starting with the given value.
+    - ENDS_WITH: Matches strings ending with the given value.
+    - CONTAINS: Matches strings containing the given value.
+    - EQUALS: Matches strings exactly equal to the given value.
+    - NOT_STARTS_WITH: Excludes strings starting with the given value.
+    - NOT_ENDS_WITH: Excludes strings ending with the given value.
+    - NOT_CONTAINS: Excludes strings containing the given value.
+    """
+
+    STARTS_WITH = "starts_with"
+    ENDS_WITH = "ends_with"
+    CONTAINS = "contains"
+    EQUALS = "equals"
+    NOT_STARTS_WITH = "not_starts_with"
+    NOT_ENDS_WITH = "not_ends_with"
+    NOT_CONTAINS = "not_contains"
+
+
+class _AdvancedSearchParam(BaseParam[str]):
+    """Advanced search parameter supporting multiple match types."""
+
+    def __init__(
+        self, attribute: ColumnElement, pattern_type: SearchPatternEnum, 
skip_none: bool = True
+    ) -> None:
+        self.attribute: ColumnElement = attribute
+        self.pattern_type: SearchPatternEnum = pattern_type
+        self.value: str | None = None
+        self.skip_none = skip_none
+
+    def set_value(self, value: str | None) -> _AdvancedSearchParam:
+        self.value = value
+        return self
+
+    def to_orm(self, select: Select) -> Select:
+        """Apply the appropriate filter to the SQLAlchemy query based on the 
match type."""
+        if self.value is None and self.skip_none:
+            return select
+
+        pattern_map = {
+            SearchPatternEnum.STARTS_WITH: f"{self.value}%",
+            SearchPatternEnum.ENDS_WITH: f"%{self.value}",
+            SearchPatternEnum.CONTAINS: f"%{self.value}%",
+            SearchPatternEnum.EQUALS: self.value,
+            SearchPatternEnum.NOT_STARTS_WITH: f"{self.value}%",
+            SearchPatternEnum.NOT_ENDS_WITH: f"%{self.value}",
+            SearchPatternEnum.NOT_CONTAINS: f"%{self.value}%",
+        }

Review Comment:
   All that is really focused around `search` (text search) while I imagined 
`advanced` search to actually be on any field and any db operation.
   
   Like a want a custom query to display dags with the specific status that is 
`SUCCESS` and with the `dag_id` that ends with `something` and  `is_paused` 
True.
   
   Basically serializing and deserializing via a query parameter 
`&query='xxxxx'` dyanamic Filters.



##########
airflow/api_fastapi/common/parameters.py:
##########
@@ -146,6 +147,127 @@ def depends_search(value: str | None = 
Query(alias=pattern_name, default=None))
     return depends_search
 
 
+class SearchPatternEnum(Enum):
+    """
+    Enum representing the types of search patterns supported.
+
+    - STARTS_WITH: Matches strings starting with the given value.
+    - ENDS_WITH: Matches strings ending with the given value.
+    - CONTAINS: Matches strings containing the given value.
+    - EQUALS: Matches strings exactly equal to the given value.
+    - NOT_STARTS_WITH: Excludes strings starting with the given value.
+    - NOT_ENDS_WITH: Excludes strings ending with the given value.
+    - NOT_CONTAINS: Excludes strings containing the given value.
+    """
+
+    STARTS_WITH = "starts_with"
+    ENDS_WITH = "ends_with"
+    CONTAINS = "contains"
+    EQUALS = "equals"
+    NOT_STARTS_WITH = "not_starts_with"
+    NOT_ENDS_WITH = "not_ends_with"
+    NOT_CONTAINS = "not_contains"

Review Comment:
   I think we need a private endpoint for that ? 



##########
airflow/api_fastapi/common/parameters.py:
##########
@@ -146,6 +147,127 @@ def depends_search(value: str | None = 
Query(alias=pattern_name, default=None))
     return depends_search
 
 
+class SearchPatternEnum(Enum):
+    """
+    Enum representing the types of search patterns supported.
+
+    - STARTS_WITH: Matches strings starting with the given value.
+    - ENDS_WITH: Matches strings ending with the given value.
+    - CONTAINS: Matches strings containing the given value.
+    - EQUALS: Matches strings exactly equal to the given value.
+    - NOT_STARTS_WITH: Excludes strings starting with the given value.
+    - NOT_ENDS_WITH: Excludes strings ending with the given value.
+    - NOT_CONTAINS: Excludes strings containing the given value.
+    """
+
+    STARTS_WITH = "starts_with"
+    ENDS_WITH = "ends_with"
+    CONTAINS = "contains"
+    EQUALS = "equals"
+    NOT_STARTS_WITH = "not_starts_with"
+    NOT_ENDS_WITH = "not_ends_with"
+    NOT_CONTAINS = "not_contains"

Review Comment:
   Also an endpoint to list `resource` fields, and type, so we can 
appropriately display the UI form.
   
   For instance DAGModel has a field called `is_active` which is a boolean 
etc.. etc.... (So we can basically list fields, operators, and then compos 
fields + operators do construct a dynamic query)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to