Преглед изворни кода

Finish Database.search() (closes #19)

tags/v1.0^2
Ben Kurtovic пре 10 година
родитељ
комит
860260d0ad
3 измењених фајлова са 45 додато и 15 уклоњено
  1. +39
    -10
      bitshift/database/__init__.py
  2. +1
    -1
      bitshift/query/__init__.py
  3. +5
    -4
      bitshift/query/nodes.py

+ 39
- 10
bitshift/database/__init__.py Прегледај датотеку

@@ -9,6 +9,7 @@ import mmh3
import oursql import oursql


from .migration import VERSION, MIGRATIONS from .migration import VERSION, MIGRATIONS
from ..codelet import Codelet
from ..query.nodes import (String, Regex, Text, Language, Author, Date, Symbol, from ..query.nodes import (String, Regex, Text, Language, Author, Date, Symbol,
BinaryOp, UnaryOp) BinaryOp, UnaryOp)


@@ -65,7 +66,35 @@ class Database(object):
num_results = 0 # TODO: NotImplemented num_results = 0 # TODO: NotImplemented
return ids, num_results return ids, num_results


def _get_codelets_from_ids(self, ids):
def _get_authors_for_codelet(self, cursor, codelet_id):
"""Return a list of authors for a given codelet."""
query = """SELECT author_name, author_url
FROM authors
WHERE author_codelet = ?"""

cursor.execute(query, (codelet_id,))
return cursor.fetchall()

def _get_symbols_for_code(self, cursor, code_id):
"""Return a list of symbols for a given codelet."""
query = """SELECT symbol_type, symbol_name, sloc_type, sloc_row,
sloc_col, sloc_end_row, sloc_end_col
FROM symbols
INNER JOIN symbol_locations ON sloc_symbol = symbol_id
WHERE symbol_code = ?"""

symbols = {type_: {} for type_ in Symbol.TYPES_INV}
cursor.execute(query, (code_id,))
for type_, name, loc_type, row, col, erow, ecol in cursor.fetchall():
sdict = symbols[Symbol.TYPES_INV[type_]]
if name not in sdict:
sdict[name] = ((), ())
sdict[name][loc_type].append((row, col, erow, ecol))
for type_, sdict in symbols.items():
symbols[type_] = [(n, d, u) for n, (d, u) in sdict.iteritems()]
return symbols

def _get_codelets_from_ids(self, cursor, ids):
"""Return a list of Codelet objects given a list of codelet IDs.""" """Return a list of Codelet objects given a list of codelet IDs."""
query = """SELECT * query = """SELECT *
FROM codelets FROM codelets
@@ -73,17 +102,18 @@ class Database(object):
INNER JOIN origins ON codelet_origin = origin_id INNER JOIN origins ON codelet_origin = origin_id
WHERE codelet_id = ?""" WHERE codelet_id = ?"""


with self._conn.cursor(oursql.DictCursor) as cursor:
cursor.executemany(query, [(id,) for id in ids])
for row in cursor.fetchone():
with self._conn.cursor(oursql.DictCursor) as dict_cursor:
dict_cursor.executemany(query, [(id,) for id in ids])
for row in dict_cursor.fetchone():
codelet_id = row["codelet_id"]
if row["origin_url_base"]: if row["origin_url_base"]:
url = row["codelet_url"] url = row["codelet_url"]
else: else:
url = row["origin_url_base"] + row["codelet_url"] url = row["origin_url_base"] + row["codelet_url"]
origin = (row["origin_name"], row["origin_url"], origin = (row["origin_name"], row["origin_url"],
row["origin_image"]) row["origin_image"])
authors = NotImplemented # TODO: list of 3-tuples (author_name, author_url or None)
symbols = NotImplemented # TODO: dict of {sym_type: (name, decls, uses)}
authors = self._get_authors_for_codelet(cursor, codelet_id)
symbols = self._get_symbols_for_code(cursor, row["code_id"])
yield Codelet( yield Codelet(
row["codelet_name"], row["code_code"], None, row["codelet_name"], row["code_code"], None,
row["code_lang"], authors, url, row["code_lang"], authors, url,
@@ -103,13 +133,12 @@ class Database(object):


def _insert_symbols(self, cursor, code_id, sym_type, symbols): def _insert_symbols(self, cursor, code_id, sym_type, symbols):
"""Insert a list of symbols of a given type into the database.""" """Insert a list of symbols of a given type into the database."""
sym_types = ["functions", "classes", "variables"]
query1 = "INSERT INTO symbols VALUES (DEFAULT, ?, ?, ?)" query1 = "INSERT INTO symbols VALUES (DEFAULT, ?, ?, ?)"
query2 = """INSERT INTO symbol_locations VALUES query2 = """INSERT INTO symbol_locations VALUES
(DEFAULT, ?, ?, ?, ?, ?, ?)""" (DEFAULT, ?, ?, ?, ?, ?, ?)"""


for (name, decls, uses) in symbols: for (name, decls, uses) in symbols:
cursor.execute(query1, (code_id, sym_types.index(sym_type), name))
cursor.execute(query1, (code_id, Symbol.TYPES_INV[sym_type], name))
sym_id = cursor.lastrowid sym_id = cursor.lastrowid
params = ([tuple([sym_id, 0] + list(loc)) for loc in decls] + params = ([tuple([sym_id, 0] + list(loc)) for loc in decls] +
[tuple([sym_id, 1] + list(loc)) for loc in uses]) [tuple([sym_id, 1] + list(loc)) for loc in uses])
@@ -153,8 +182,8 @@ class Database(object):
num_mnt = num_results / (10 ** num_exp) num_mnt = num_results / (10 ** num_exp)
cursor.execute(query2, (cache_id, num_mnt, num_exp)) cursor.execute(query2, (cache_id, num_mnt, num_exp))
cursor.executemany(query3, [(cache_id, c_id) for c_id in ids]) cursor.executemany(query3, [(cache_id, c_id) for c_id in ids])
codelet_gen = self._get_codelets_from_ids(ids)
return (num_results, list(codelet_gen))
codelet_gen = self._get_codelets_from_ids(cursor, ids)
return (num_results, list(codelet_gen))


def insert(self, codelet): def insert(self, codelet):
""" """


+ 1
- 1
bitshift/query/__init__.py Прегледај датотеку

@@ -231,7 +231,7 @@ class _QueryParser(object):
index = nest.index(UnaryOp.NOT) index = nest.index(UnaryOp.NOT)
if index == len(nest) - 1: if index == len(nest) - 1:
err = "Invalid query: '%s' given without argument." err = "Invalid query: '%s' given without argument."
raise QueryParseException(err % UnaryOp.OPS[op])
raise QueryParseException(err % UnaryOp.OPS[UnaryOp.NOT])
right = UnaryOp(UnaryOp.NOT, self._parse_nest(nest[index + 1:])) right = UnaryOp(UnaryOp.NOT, self._parse_nest(nest[index + 1:]))
if index > 0: if index > 0:
left = self._parse_nest(nest[:index]) left = self._parse_nest(nest[:index])


+ 5
- 4
bitshift/query/nodes.py Прегледај датотеку

@@ -190,11 +190,12 @@ class Symbol(_Node):


Searches in symbol_type and symbol_name. Searches in symbol_type and symbol_name.
""" """
ALL = 0
FUNCTION = 1
CLASS = 2
VARIABLE = 3
ALL = -1
FUNCTION = 0
CLASS = 1
VARIABLE = 2
TYPES = {FUNCTION: "FUNCTION", CLASS: "CLASS", VARIABLE: "VARIABLE"} TYPES = {FUNCTION: "FUNCTION", CLASS: "CLASS", VARIABLE: "VARIABLE"}
TYPES_INV = ["functions", "classes", "variables"]


def __init__(self, type_, name): def __init__(self, type_, name):
""" """


Loading…
Откажи
Сачувај