| @@ -1,5 +1,4 @@ | |||||
| from .associations import BinaryOp, UnaryOp | |||||
| from .node import Node | |||||
| from .nodes import * ## TODO | |||||
| from .tree import Tree | from .tree import Tree | ||||
| __all__ = ["parse_query"] | __all__ = ["parse_query"] | ||||
| @@ -8,20 +7,18 @@ def parse_query(query): | |||||
| """ | """ | ||||
| Parse a search query. | Parse a search query. | ||||
| The result is normalized with a sorting function so that ``"foo OR bar"`` | |||||
| and ``"bar OR foo"`` result in the same tree. This is important for caching | |||||
| purposes. | |||||
| :param query: The query be converted. | :param query: The query be converted. | ||||
| :type query: str | :type query: str | ||||
| :return: A tree storing the data in the query. | :return: A tree storing the data in the query. | ||||
| :rtype: :py:class:`~.query.tree.Tree` | :rtype: :py:class:`~.query.tree.Tree` | ||||
| """ | """ | ||||
| "bubble sort lang:python" | |||||
| # gets a string, returns a Tree | |||||
| # TODO: note: resultant Trees should be normalized so that "foo OR bar" | |||||
| # and "bar OR foo" result in equivalent trees | |||||
| pass | pass | ||||
| # "foo" -> Tree() | |||||
| # "foo bar" -> "foo bar" OR ("foo" or "bar") | |||||
| # "foo bar baz" -> ""foo bar baz" OR ("foo" OR "bar baz") OR ("foo" OR "bar baz") OR ('foo' OR 'bar' OR 'baz')" | |||||
| @@ -1,29 +0,0 @@ | |||||
| __all__ = ["BinaryOp", "UnaryOp"] | |||||
| class _Association(object): | |||||
| pass | |||||
| class BinaryOp(_Association): | |||||
| AND = 1 | |||||
| OR = 2 | |||||
| def __init__(self, left, right, op): | |||||
| self.left = left | |||||
| self.right = right | |||||
| self.op = op | |||||
| def __str__(self): | |||||
| ops = {AND: "And", OR: "Or"} | |||||
| return "{0}({1}, {2})".format(ops[self.op], self.left, self.right) | |||||
| class UnaryOp(_Association): | |||||
| NOT = 1 | |||||
| def __init__(self, node, op): | |||||
| self.node = node | |||||
| self.op = op | |||||
| def __str__(self): | |||||
| pass | |||||
| @@ -1,4 +0,0 @@ | |||||
| __all__ = ["Node"] | |||||
| class Node(object): | |||||
| pass | |||||
| @@ -0,0 +1,81 @@ | |||||
| __all__ = ["Node", "Text", "BinaryOp", "UnaryOp"] | |||||
| class _Literal(object): | |||||
| """Represents a literal component of a search query, present at the leaves. | |||||
| A literal might be a string or a regular expression. | |||||
| """ | |||||
| pass | |||||
| class _String(_Literal) | |||||
| """Represents a string literal.""" | |||||
| def __init__(self, string): | |||||
| self.string = string | |||||
| def __repr__(self): | |||||
| return "String({0!r})".format(self.string) | |||||
| class _Regex(_Literal): | |||||
| """Represents a regular expression literal.""" | |||||
| def __init__(self, regex): | |||||
| self.regex = regex | |||||
| def __repr__(self): | |||||
| return "Regex({0!r})".format(self.regex) | |||||
| class Node(object): | |||||
| """Represents a single node in a query tree.""" | |||||
| pass | |||||
| class Text(Node): | |||||
| """Represents a text node. | |||||
| Searches in codelet names (full-text search), symbols (equality), and | |||||
| source code (full-text search). | |||||
| """ | |||||
| def __init__(self, text): | |||||
| self.text = text | |||||
| def __repr__(self): | |||||
| return "Text({0})".format(self.text) | |||||
| # Language -> code_lang (direct) | |||||
| # DateRange -> codelet_date_created (cmp), codelet_date_modified (cmp) | |||||
| # Author -> author_name (FTS) | |||||
| # Symbol -> func, class, var -> symbol_type, symbol_name (direct) | |||||
| class BinaryOp(Node): | |||||
| """Represents a relationship between two nodes: ``and``, ``or``.""" | |||||
| AND = 1 | |||||
| OR = 2 | |||||
| def __init__(self, left, right, op): | |||||
| self.left = left | |||||
| self.right = right | |||||
| self.op = op | |||||
| def __repr__(self): | |||||
| ops = {self.AND: "And", self.OR: "Or"} | |||||
| return "{0}({1}, {2})".format(ops[self.op], self.left, self.right) | |||||
| class UnaryOp(Node): | |||||
| """Represents a transformation applied to one node: ``not``.""" | |||||
| NOT = 1 | |||||
| def __init__(self, node, op): | |||||
| self.node = node | |||||
| self.op = op | |||||
| def __repr__(self): | |||||
| ops = {self.NOT: "Not"} | |||||
| return "{0}({1})".format(ops[self.op], self.node) | |||||
| @@ -1,4 +1,13 @@ | |||||
| __all__ = ["Tree"] | __all__ = ["Tree"] | ||||
| class Tree(object): | class Tree(object): | ||||
| pass | |||||
| """Represents a query tree.""" | |||||
| def __init__(self, root): | |||||
| self._root = root | |||||
| def serialize(self): | |||||
| pass | |||||
| def build_query(self): | |||||
| pass | |||||