summaryrefslogtreecommitdiff
path: root/python/qadmin.py
diff options
context:
space:
mode:
authorMarko Kreen2010-11-25 12:19:18 +0000
committerMarko Kreen2010-11-25 12:19:18 +0000
commit7d2c2fd00e39c16e7d88796ab07c67e691ce9c0b (patch)
tree17052af2406f84e94f15f835cf9784cfe4fd0ac4 /python/qadmin.py
parent7c985ab39451e9133fc5c06cef6e123cfc3ab5b9 (diff)
qadmin; better quoting support
Diffstat (limited to 'python/qadmin.py')
-rwxr-xr-xpython/qadmin.py101
1 files changed, 62 insertions, 39 deletions
diff --git a/python/qadmin.py b/python/qadmin.py
index a31e2a75..c181268a 100755
--- a/python/qadmin.py
+++ b/python/qadmin.py
@@ -91,16 +91,13 @@ IGNORE_HOSTS = {
'ip6-mcastprefix': 1,
}
-def unquote_any(s):
+def normalize_any(s):
if s:
c = s[0]
if c == "'":
s = skytools.unquote_literal(s, stdstr = True)
- elif c == '"':
- s = skytools.unquote_ident(s)
- # extquote?
else:
- s = s.lower()
+ s = skytools.unquote_fqident(s)
return s
def display_result(curs, desc, fields = []):
@@ -166,7 +163,6 @@ class List(Token):
self.tok_list = args
def get_next(self, typ, word, params):
- cw = word.lower()
for w in self.tok_list:
n = w.get_next(typ, word, params)
if n:
@@ -223,7 +219,7 @@ class DynIdentList(DynList):
"""Allow quoted queue names"""
next = DynList.get_next(self, typ, word, params)
if next and self.name:
- params[self.name] = unquote_any(word)
+ params[self.name] = normalize_any(word)
return next
class Queue(DynIdentList):
@@ -476,21 +472,41 @@ class AdminConsole:
q = "select distinct node_name from pgq_node.node_location order by 1"
return self._ccache('node_list', q, 'pgq_node')
- def get_new_table_list(self):
- if not self.cur_queue:
- return []
- qname = skytools.quote_literal(self.cur_queue)
- q = """select n.nspname || '.' || r.relname
+ def _new_obj_sql(self, queue, objname, objkind):
+ args = {'queue': skytools.quote_literal(queue),
+ 'obj': objname,
+ 'ifield': objname + '_name',
+ 'itable': 'londiste.' + objname + '_info',
+ 'kind': skytools.quote_literal(objkind),
+ }
+ q = """select quote_ident(n.nspname) || '.' || quote_ident(r.relname)
from pg_catalog.pg_class r
join pg_catalog.pg_namespace n on (n.oid = r.relnamespace)
- left join londiste.table_info i on (i.queue_name = %s and i.table_name = (n.nspname || '.' || r.relname))
- where r.relkind='r'
+ left join %(itable)s i
+ on (i.queue_name = %(queue)s and
+ i.%(ifield)s = (n.nspname || '.' || r.relname))
+ where r.relkind = %(kind)s
and n.nspname not in ('pg_catalog', 'information_schema', 'pgq', 'londiste', 'pgq_node', 'pgq_ext')
and n.nspname !~ 'pg_.*'
- and i.table_name is null
- order by 1 """ % qname
+ and i.%(ifield)s is null
+ union all
+ select londiste.quote_fqname(%(ifield)s) from %(itable)s
+ where queue_name = %(queue)s and not local
+ order by 1 """ % args
+ return q
+
+ def get_new_table_list(self):
+ if not self.cur_queue:
+ return []
+ q = self._new_obj_sql(self.cur_queue, 'table', 'r')
return self._ccache('new_table_list', q, 'londiste')
+ def get_new_seq_list(self):
+ if not self.cur_queue:
+ return []
+ q = self._new_obj_sql(self.cur_queue, 'seq', 'S')
+ return self._ccache('new_seq_list', q, 'londiste')
+
def get_known_table_list(self):
if not self.cur_queue:
return []
@@ -499,21 +515,6 @@ class AdminConsole:
" where queue_name = %s order by 1" % qname
return self._ccache('known_table_list', q, 'londiste')
- def get_new_seq_list(self):
- if not self.cur_queue:
- return []
- qname = skytools.quote_literal(self.cur_queue)
- q = """select n.nspname || '.' || r.relname
- from pg_catalog.pg_class r
- join pg_catalog.pg_namespace n on (n.oid = r.relnamespace)
- left join londiste.seq_info i on (i.queue_name = %s and i.seq_name = (n.nspname || '.' || r.relname))
- where r.relkind='S'
- and n.nspname not in ('pg_catalog', 'information_schema', 'pgq', 'londiste', 'pgq_node', 'pgq_ext')
- and n.nspname !~ 'pg_.*'
- and i.seq_name is null
- order by 1 """ % qname
- return self._ccache('new_seq_list', q, 'londiste')
-
def get_known_seq_list(self):
if not self.cur_queue:
return []
@@ -681,7 +682,9 @@ class AdminConsole:
def main_loop(self):
readline.parse_and_bind('tab: complete')
readline.set_completer(self.rl_completer_safe)
- #print 'delims: ', repr(readline.get_completer_delims())
+ print 'delims: ', repr(readline.get_completer_delims())
+ # remove " from delims
+ readline.set_completer_delims(" \t\n`~!@#$%^&*()-=+[{]}\\|;:',<>/?")
hist_file = os.path.expanduser("~/.qadmin_history")
try:
@@ -734,46 +737,66 @@ class AdminConsole:
return skytools.sql_tokenizer(sql,
standard_quoting = True,
fqident = True,
+ show_location = True,
ignore_whitespace = True)
def reset_comp_cache(self):
self.comp_cache = {}
def find_suggestions(self, pfx, curword, params = {}):
+
+ # refresh word cache
c_pfx = self.comp_cache.get('comp_pfx')
c_list = self.comp_cache.get('comp_list', [])
+ c_pos = self.comp_cache.get('comp_pos')
if c_pfx != pfx:
- c_list = self.find_suggestions_real(pfx, params)
+ c_list, c_pos = self.find_suggestions_real(pfx, params)
+ while c_pos < len(pfx) and pfx[c_pos].isspace():
+ c_pos += 1
self.comp_cache['comp_pfx'] = pfx
self.comp_cache['comp_list'] = c_list
+ self.comp_cache['comp_pos'] = c_pos
+ skip = len(pfx) - c_pos
+ if skip:
+ curword = pfx[c_pos : ] + curword
+
+ # generate suggestions
wlen = len(curword)
res = []
for cword in c_list:
if curword == cword[:wlen]:
res.append(cword)
+
+ # resync with readline offset
+ if skip:
+ res = [s[skip:] for s in res]
+ #print '\nfind_suggestions', repr(pfx), repr(curword), repr(res)
return res
def find_suggestions_real(self, pfx, params):
# find level
node = top_level
- for typ, w in self.sql_words(pfx):
- w = w.lower()
+ pos = 0
+ for typ, w, pos in self.sql_words(pfx):
+ if typ == 'ident':
+ w = normalize_any(w)
node = node.get_next(typ, w, params)
if not node:
break
# find possible matches
if node:
- return node.get_completions(params)
+ return (node.get_completions(params), pos)
else:
- return []
+ return ([], pos)
def exec_string(self, ln, eof = False):
node = top_level
params = {}
- for typ, w in self.sql_words(ln):
- w = w.lower()
+ for typ, w, pos in self.sql_words(ln):
+ if typ == 'ident':
+ w = normalize_any(w)
#print repr(typ), repr(w)
if typ == 'error':
print 'syntax error 1:', repr(ln)