:PROPERTIES: :ID: 7b0f97f3-9037-4d05-9170-a478e97c8d1f :END: #+title: Translating the search DSL Defining and translating the Search DSL for the [[id:11edd6c9-b976-403b-a419-b5542ddedaae][Subscriber Search Service]]. * Searches ** A search is a collection of groupings #+begin_src python :noweb-ref search @dataclasses.dataclass class Search: conditions: typing.List[Group] #+end_src ** A grouping is a collection of conditions #+begin_src python :noweb-ref group class GroupType(enum.Enum): AND = 1 # TODO: OR = 2 @dataclasses.dataclass class Group: group_type: GroupType conditions: typing.List[Condition] #+end_src ** A condition is a boolean expression applied to a field #+begin_src python :noweb-ref condition @dataclasses.dataclass class Condition: field: Field operator: str value: typing.Optional[str] #+end_src ** A field refers to a specific database field somewhere in our system #+begin_src python :noweb-ref field class Database(enum.Enum): AppDB = 1 Analytics = 2 @dataclasses.dataclass class FieldType: name: str @dataclasses.dataclass class Field: name: str column: str table: str database: Database #+end_src ** Allowable conditions * Decisions ** Should the input type presented to the end-user be tied to the database field or the conditional operator? Seems it should be the operator, as an "equals" operator would match a single value, whereas an "in" operator would match against multiple. That said, it could be /parameterized/ by the field's type (e.g. a tag has type =str=, its "equals" operator has type =str=, its "in" operator has type =List[str]=). * Code #+begin_src python :noweb yes :noweb-ref final :exports code :results silent import dataclasses import enum import typing <> <> <> <> #+end_src