Browse Source

Fix _parse_node; _parse_term quote handling; should probably refactor.

tags/v1.0^2
Ben Kurtovic 10 years ago
parent
commit
8fbfd4c45c
2 changed files with 16 additions and 13 deletions
  1. +12
    -13
      bitshift/database/__init__.py
  2. +4
    -0
      bitshift/query/__init__.py

+ 12
- 13
bitshift/database/__init__.py View File

@@ -55,45 +55,44 @@ class Database(object):


def _explode_query_tree(self, tree): def _explode_query_tree(self, tree):
"""Convert a query tree into components of an SQL SELECT statement.""" """Convert a query tree into components of an SQL SELECT statement."""
def _parse_node(node):
def _parse_node(node, tables):
if isinstance(node, Text): if isinstance(node, Text):
tables |= {"code", "symbols"} tables |= {"code", "symbols"}
# (FTS: codelet_name, =: symbol_name, FTS: code_code) vs. node.text (_Literal) # (FTS: codelet_name, =: symbol_name, FTS: code_code) vs. node.text (_Literal)
pass pass
elif isinstance(node, Language): elif isinstance(node, Language):
tables |= {"code"} tables |= {"code"}
return "(code_lang = ?)", [node.lang]
return "(code_lang = ?)", tables, [node.lang]
elif isinstance(node, Author): elif isinstance(node, Author):
tables |= {"authors"} tables |= {"authors"}
if isinstance(node.name, Regex): if isinstance(node.name, Regex):
return "(author_name REGEXP ?)", [node.name.regex] return "(author_name REGEXP ?)", [node.name.regex]
cond = "(MATCH(author_name) AGAINST (? IN BOOLEAN MODE))" cond = "(MATCH(author_name) AGAINST (? IN BOOLEAN MODE))"
return cond, [node.name.string]
return cond, tables, [node.name.string]
elif isinstance(node, Date): elif isinstance(node, Date):
column = {node.CREATE: "codelet_date_created", column = {node.CREATE: "codelet_date_created",
node.MODIFY: "codelet_date_modified"}[node.type] node.MODIFY: "codelet_date_modified"}[node.type]
op = {node.BEFORE: "<=", node.AFTER: ">="}[node.relation] op = {node.BEFORE: "<=", node.AFTER: ">="}[node.relation]
return "(" + column + " " + op + " ?)", [node.date]
return "(" + column + " " + op + " ?)", tables, [node.date]
elif isinstance(node, Symbol): elif isinstance(node, Symbol):
tables |= {"symbols"} tables |= {"symbols"}
cond_base = "(symbol_type = ? AND symbol_name = ?)" cond_base = "(symbol_type = ? AND symbol_name = ?)"
if node.type != node.ALL: if node.type != node.ALL:
return cond_base, [node.type, node.name]
return cond_base, tables, [node.type, node.name]
cond = "(" + " OR ".join([cond_base] * len(node.TYPES)) + ")" cond = "(" + " OR ".join([cond_base] * len(node.TYPES)) + ")"
args = zip(node.TYPES.keys(), [node.name] * len(node.TYPES)) args = zip(node.TYPES.keys(), [node.name] * len(node.TYPES))
return cond, [arg for tup in args for arg in tup]
return cond, tables, [arg for tup in args for arg in tup]
elif isinstance(node, BinaryOp): elif isinstance(node, BinaryOp):
left_cond, left_args = _parse_node(node.left)
right_cond, right_args = _parse_node(node.right)
left_cond, tbls, left_args = _parse_node(node.left, tables)
right_cond, tables, right_args = _parse_node(node.right, tbls)
op = node.OPS[node.op] op = node.OPS[node.op]
cond = "(" + left_cond + " " + op + " " + right_cond + ")" cond = "(" + left_cond + " " + op + " " + right_cond + ")"
return cond, left_args + right_args
return cond, tables, left_args + right_args
elif isinstance(node, UnaryOp): elif isinstance(node, UnaryOp):
cond, args = _parse_node(node.node)
return "(" + node.OPS[node.op] + " " + cond + ")", args
cond, tables, args = _parse_node(node.node, tables)
return "(" + node.OPS[node.op] + " " + cond + ")", tables, args


tables = set()
conditional, arglist = _parse_node(tree.root)
conditional, tables, arglist = _parse_node(tree.root, set())
# joins = " ".join(tables) # joins = " ".join(tables)


return conditional, joins, tuple(arglist) return conditional, joins, tuple(arglist)


+ 4
- 0
bitshift/query/__init__.py View File

@@ -116,6 +116,10 @@ class _QueryParser(object):


def _parse_term(self, term): def _parse_term(self, term):
"""Parse a query term into a tree node and return it.""" """Parse a query term into a tree node and return it."""
try:
term = term.decode("unicode_escape")
except UnicodeDecodeError:
raise QueryParseException('Invalid query term: "%s"' % term)
if ":" in term and not term[0] == ":": if ":" in term and not term[0] == ":":
prefix, arg = term.split(":", 1) prefix, arg = term.split(":", 1)
invert = prefix.lower() == "not" invert = prefix.lower() == "not"


Loading…
Cancel
Save