diff --git a/bitshift/query/nodes.py b/bitshift/query/nodes.py index 68bf504..342f8ec 100644 --- a/bitshift/query/nodes.py +++ b/bitshift/query/nodes.py @@ -89,14 +89,13 @@ class Text(_Node): if isinstance(self.text, Regex): ranks = ["(codelet_name REGEXP ?)", "(symbol_name REGEXP ?)", "(code_code REGEXP ?)"] - cond = "(" + " OR ".join(ranks) + ")" - return cond, ranks, [self.text.regex] * 3 + text = self.text.regex else: ranks = ["(MATCH(codelet_name) AGAINST (? IN BOOLEAN MODE))", "(MATCH(code_code) AGAINST (? IN BOOLEAN MODE))", "(symbol_name = ?)"] - cond = "(" + " OR ".join(ranks) + ")" - return cond, ranks, [self.text.string] * 3 + text = self.text.string + return cond, ranks, [text] * 3 class Language(_Node): @@ -199,7 +198,7 @@ class Symbol(_Node): def __init__(self, type_, name): """ :type type_: int (``ALL``, ``FUNCTION``, ``CLASS``, etc.) - :type name: :py:class:`.Literal` + :type name: :py:class:`._Literal` """ self.type = type_ self.name = name @@ -212,14 +211,18 @@ class Symbol(_Node): return self.name.sortkey() def parameterize(self, tables): - tables |= {"symbols"} - cond_base = "(symbol_type = ? AND symbol_name = ?)" + tables |= {"code", "symbols"} + if isinstance(self.name, Regex): + cond_base = "(symbol_type = ? AND symbol_name REGEXP ?)" + name = self.name.regex + else: + cond_base = "(symbol_type = ? AND symbol_name = ?)" + name = self.name.string if self.type != self.ALL: - return cond_base, [], [self.type, self.name] - ranks = [cond_base] * len(self.TYPES) - cond = "(" + " OR ".join(ranks) + ")" - args = zip(self.TYPES.keys(), [self.name] * len(self.TYPES)) - return cond, ranks, [arg for tup in args for arg in tup] + return cond_base, [], [self.type, name] + cond = "(" + " OR ".join([cond_base] * len(self.TYPES)) + ")" + args = zip(self.TYPES.keys(), [name] * len(self.TYPES)) + return cond, [], [arg for tup in args for arg in tup] class BinaryOp(_Node): diff --git a/bitshift/query/tree.py b/bitshift/query/tree.py index cc03f72..86392be 100644 --- a/bitshift/query/tree.py +++ b/bitshift/query/tree.py @@ -46,12 +46,22 @@ class Tree(object): :return: SQL query data. :rtype: 2-tuple of (SQL statement string, query parameter tuple) """ + def get_table_join(table): + tables = { + "code": ("codelet_code_id", "code_id"), + "authors": ("author_codelet", "codelet_id"), + "symbols": ("symbol_code", "code_id") + } + tmpl = "INNER JOIN %s ON %s = %s" + return tmpl % (table, tables[table][0], tables[table][1]) + tables = set() cond, ranks, arglist = self._root.parameterize(tables) ranks = ranks or [cond] score = "((%s) / %d)" % (" + ".join(ranks), len(ranks)) - joins = " ".join(tables) # TODO + joins = " ".join(get_table_join(table) for table in tables) offset = (page - 1) * page_size + ## TODO: handle pretty query = QUERY_TEMPLATE % (score, joins, cond, page_size, offset) return query, tuple(arglist * 2)