A semantic search engine for source code https://bitshift.benkurtovic.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

70 lines
2.1 KiB

  1. __all__ = ["Tree"]
  2. QUERY_TEMPLATE = """SELECT codelet_id, (codelet_rank%s) AS score
  3. FROM codelets %s
  4. WHERE %s
  5. GROUP BY codelet_id
  6. ORDER BY score DESC
  7. LIMIT %d OFFSET %d""".replace("\n", " ")
  8. class Tree(object):
  9. """Represents a query tree."""
  10. def __init__(self, root):
  11. self._root = root
  12. def __repr__(self):
  13. return "Tree({0})".format(self._root)
  14. @property
  15. def root(self):
  16. """The root node of the tree."""
  17. return self._root
  18. def sortkey(self):
  19. """Return a string sort key for the query tree."""
  20. return self._root.sortkey()
  21. def serialize(self):
  22. """Create a string representation of the query for caching.
  23. :return: Query string representation.
  24. :rtype: str
  25. """
  26. return repr(self)
  27. def build_query(self, page=1, page_size=10):
  28. """Convert the query tree into a parameterized SQL SELECT statement.
  29. :param page: The page number to get results for.
  30. :type page: int
  31. :param page_size: The number of results per page.
  32. :type page_size: int
  33. :return: SQL query data.
  34. :rtype: 2-tuple of (SQL statement string, query parameter tuple)
  35. """
  36. def get_table_joins(tables):
  37. data = [
  38. ("code", "codelet_code_id", "code_id"),
  39. ("authors", "author_codelet", "codelet_id"),
  40. ("symbols", "symbol_code", "code_id")
  41. ]
  42. tmpl = "INNER JOIN %s ON %s = %s"
  43. for args in data:
  44. if args[0] in tables:
  45. yield tmpl % args
  46. tables = set()
  47. cond, arglist, ranks, need_ranks = self._root.parameterize(tables)
  48. ranks = ranks or [cond]
  49. if need_ranks:
  50. score = " + ((%s) / %d)" % (" + ".join(ranks), len(ranks))
  51. else:
  52. score = ""
  53. joins = " ".join(get_table_joins(tables))
  54. offset = (page - 1) * page_size
  55. query = QUERY_TEMPLATE % (score, joins, cond, page_size, offset)
  56. return query, tuple(arglist * 2 if need_ranks else arglist)