1
1
mirror of https://github.com/dbcli/pgcli.git synced 2024-10-06 10:17:15 +03:00

Merge pull request #554 from dbcli/koljonen/suggestion_sorting

Some changes to sorting of suggestions
This commit is contained in:
Amjith Ramanujam 2016-07-29 07:33:37 -07:00 committed by GitHub
commit fb23a1e4ec
2 changed files with 30 additions and 21 deletions

View File

@ -233,7 +233,7 @@ class PGCompleter(Completer):
def find_matches(self, text, collection, mode='fuzzy',
meta=None, meta_collection=None,
type_priority=0, priority_collection = None):
priority_collection = None):
"""Find completion matches for the given text.
Given the user's input text and a collection of available
@ -249,6 +249,10 @@ class PGCompleter(Completer):
"""
type_priority = [
'keyword', 'function', 'view', 'table', 'datatype', 'database',
'schema', 'column', 'table alias', 'join', 'name join', 'fk join'
].index(meta) if meta else -1
text = last_word(text, include='most_punctuations').lower()
text_len = len(text)
@ -319,7 +323,7 @@ class PGCompleter(Completer):
+ tuple(c for c in item))
item = self.case(item)
priority = type_priority, prio, sort_key, priority_func(item), lexical_priority
priority = sort_key, type_priority, prio, priority_func(item), lexical_priority
matches.append(Match(
completion=Completion(item, -text_len, display_meta=meta),
@ -399,7 +403,8 @@ class PGCompleter(Completer):
return [Match(completion=Completion(collist, -1,
display_meta='columns', display='*'), priority=(1,1,1))]
return self.find_matches(word_before_cursor, flat_cols, meta='column')
return self.find_matches(word_before_cursor, flat_cols,
meta='column')
def alias(self, tbl, tbls):
""" Generate a unique table alias
@ -458,7 +463,7 @@ class PGCompleter(Completer):
0 if (left.schema, left.tbl) in other_tbls else 1))
return self.find_matches(word_before_cursor, joins, meta='join',
priority_collection=prios, type_priority=100)
priority_collection=prios)
def get_join_condition_matches(self, suggestion, word_before_cursor):
col = namedtuple('col', 'schema tbl col')
@ -469,15 +474,16 @@ class PGCompleter(Completer):
ltbl, lcols = [(t, cs) for (t, cs) in tbls() if t.ref == lref][-1]
except IndexError: # The user typed an incorrect table qualifier
return []
conds, found_conds = [], set()
conds, prios, found_conds = [], [], set()
def add_cond(lcol, rcol, rref, meta, prio):
def add_cond(lcol, rcol, rref, prio):
prefix = '' if suggestion.parent else ltbl.ref + '.'
case = self.case
cond = prefix + case(lcol) + ' = ' + rref + '.' + case(rcol)
if cond not in found_conds:
found_conds.add(cond)
conds.append((cond, meta, prio + ref_prio[rref]))
conds.append(cond)
prios.append(prio + ref_prio[rref])
def list_dict(pairs): # Turns [(a, b), (a, c)] into {a: [b, c]}
d = defaultdict(list)
@ -500,20 +506,21 @@ class PGCompleter(Completer):
par = col(fk.parentschema, fk.parenttable, fk.parentcolumn)
left, right = (child, par) if left == child else (par, child)
for rtbl in coldict[right]:
add_cond(left.col, right.col, rtbl.ref, 'fk join', 2000)
add_cond(left.col, right.col, rtbl.ref, 2000)
matches = self.find_matches(word_before_cursor, conds,
meta='fk join', priority_collection=prios)
# For name matching, use a {(colname, coltype): TableReference} dict
coltyp = namedtuple('coltyp', 'name datatype')
col_table = list_dict((coltyp(c.name, c.datatype), t) for t, c in cols)
conds, prios = [], []
# Find all name-match join conditions
for c in (coltyp(c.name, c.datatype) for c in lcols):
for rtbl in (t for t in col_table[c] if t.ref != ltbl.ref):
add_cond(c.name, c.name, rtbl.ref, 'name join', 1000
add_cond(c.name, c.name, rtbl.ref, 1000
if c.datatype in ('integer', 'bigint', 'smallint') else 0)
conds, metas, prios = zip(*conds) if conds else ([], [], [])
return self.find_matches(word_before_cursor, conds,
meta_collection=metas, type_priority=100, priority_collection=prios)
return matches + self.find_matches(word_before_cursor, conds,
meta='name join', priority_collection=prios)
def get_function_matches(self, suggestion, word_before_cursor, alias=False):
if suggestion.filter == 'for_from_clause':
@ -552,7 +559,8 @@ class PGCompleter(Completer):
if not word_before_cursor.startswith('pg_'):
schema_names = [s for s in schema_names if not s.startswith('pg_')]
return self.find_matches(word_before_cursor, schema_names, meta='schema')
return self.find_matches(word_before_cursor, schema_names,
meta='schema')
def get_from_clause_item_matches(self, suggestion, word_before_cursor):
alias = self.generate_aliases
@ -574,7 +582,8 @@ class PGCompleter(Completer):
if alias:
tables = [self.case(t) + ' ' + self.alias(t, suggestion.tables)
for t in tables]
return self.find_matches(word_before_cursor, tables, meta='table')
return self.find_matches(word_before_cursor, tables,
meta='table')
def get_view_matches(self, suggestion, word_before_cursor, alias=False):

View File

@ -561,17 +561,17 @@ def test_table_names_after_from(completer, complete_event, text):
assert set(result) == set(testdata.schemas() + testdata.tables()
+ testdata.views() + testdata.functions())
assert [c.text for c in result] == [
'public',
'orders',
'"select"',
'users',
'"Users"',
'user_emails',
'_custom_fun()',
'custom_fun()',
'custom_func1()',
'custom_func2()',
'orders',
'public',
'"select"',
'set_returning_func()',
'user_emails',
'users',
'"Users"',
]
def test_auto_escaped_col_names(completer, complete_event):