diff options
Diffstat (limited to 'python/qadmin.py')
-rwxr-xr-x | python/qadmin.py | 163 |
1 files changed, 116 insertions, 47 deletions
diff --git a/python/qadmin.py b/python/qadmin.py index c181268a..e583d05b 100755 --- a/python/qadmin.py +++ b/python/qadmin.py @@ -15,8 +15,6 @@ unregister consumer foo [from <qname>]; show consumer [ <cname | *> [on <qname>] ]; - show node [ <node | *> [on <qname>] ]; - Following commands expect default queue: show batch <batch_id>; @@ -24,7 +22,9 @@ Following commands expect default queue: Londiste commands: - londiste add_table <tbl>; + londiste add_table <tbl> [ , ... ] + with skip_truncate, tgflags=urlenc, + expect_sync, skip_trigger; londiste remove_table <tbl>; londiste add_seq <seq>; londiste remove_seq <seq>; @@ -49,6 +49,23 @@ drop node status rename node +node create + +create root_node <name>; +create branch_node <name>; +create leaf_node <name>; + +alter node <name> provider <new>; + +alter node <name> takeover <oldnow> with all; +alter node <name> rename <new>; + +takeover <oldnode>; + +drop node <name>; + +show node [ <node | *> [on <qname>] ]; +show cascade; """ @@ -91,13 +108,11 @@ IGNORE_HOSTS = { 'ip6-mcastprefix': 1, } -def normalize_any(s): - if s: - c = s[0] - if c == "'": - s = skytools.unquote_literal(s, stdstr = True) - else: - s = skytools.unquote_fqident(s) +def normalize_any(typ, s): + if typ == 'str': + s = skytools.unquote_literal(s, stdstr = True) + elif typ == 'ident': + s = skytools.unquote_fqident(s) return s def display_result(curs, desc, fields = []): @@ -143,12 +158,21 @@ class Token: """ def __init__(self, **kwargs): self.name = kwargs.get('name') + self._append = kwargs.get('append', 0) def get_next(self, typ, word, params): """Return next token if 'word' matches this token.""" return None def get_completions(self, params): """Return list of all completions possible at this point.""" return [] + def set_param(self, word, params): + if not self.name: + return + if self._append: + lst = params.setdefault(self.name, []) + lst.append(word) + else: + params[self.name] = word class Proxy(Token): """Forward def for Token, in case it needs to be referenced recursively.""" @@ -166,8 +190,7 @@ class List(Token): for w in self.tok_list: n = w.get_next(typ, word, params) if n: - if self.name: - params[self.name] = word + self.set_param(word, params) return n return None @@ -198,8 +221,7 @@ class Word(Token): return None if self.word and word != self.word: return None - if self.name: # and not self.name in params: - params[self.name] = word + self.set_param(word, params) return self.next def get_completions(self, params): wlist = self.get_wlist() @@ -218,8 +240,8 @@ class DynIdentList(DynList): def get_next(self, typ, word, params): """Allow quoted queue names""" next = DynList.get_next(self, typ, word, params) - if next and self.name: - params[self.name] = normalize_any(word) + if next: + self.set_param(word, params) return next class Queue(DynIdentList): @@ -397,10 +419,47 @@ w_cons_from_queue = Word('consumer', Consumer(List(w_done, w_from_queue), name = 'consumer'), name = 'cmd2') -w_londiste_add_table = NewTable(w_done, name = 'table') -w_londiste_add_seq = NewSeq(w_done, name = 'seq') -w_londiste_remove_table = KnownTable(w_done, name = 'table') -w_londiste_remove_seq = KnownSeq(w_done, name = 'seq') +w_table_with2 = Proxy() + +w_table_with = List( + Word('skip_truncate', w_table_with2, name = 'skip_truncate'), + Word('expect_sync', w_table_with2, name = 'expect_sync'), + WordEQ('tgfmt', Value(w_table_with2, name = 'tgfmt'))) + +w_table_with2.set_real(List( + w_done, + Symbol(',', w_table_with))) + +w_londiste_add_table = Proxy() +w_londiste_add_table2 = List( + Symbol(',', w_londiste_add_table), + Word('with', w_table_with), + w_done) +w_londiste_add_table.set_real( + NewTable(w_londiste_add_table2, + name = 'tables', append = 1)) + +w_londiste_add_seq = Proxy() +w_londiste_add_seq2 = List( + Symbol(',', w_londiste_add_seq), + w_done) +w_londiste_add_seq.set_real( + NewSeq(w_londiste_add_seq2, name = 'seqs', append = 1)) + +w_londiste_remove_table = Proxy() +w_londiste_remove_table2 = List( + Symbol(',', w_londiste_remove_table), + w_done) +w_londiste_remove_table.set_real( + KnownTable(w_londiste_remove_table2, name = 'tables', append = 1)) + +w_londiste_remove_seq = KnownSeq(w_done, name = 'seqs', append = 1) +w_londiste_remove_seq = Proxy() +w_londiste_remove_seq2 = List( + Symbol(',', w_londiste_remove_seq), + w_done) +w_londiste_remove_seq.set_real( + KnownSeq(w_londiste_remove_seq2, name = 'seqs', append = 1)) w_londiste = List( Word('add_table', w_londiste_add_table), @@ -511,7 +570,8 @@ class AdminConsole: if not self.cur_queue: return [] qname = skytools.quote_literal(self.cur_queue) - q = "select table_name from londiste.table_info"\ + q = "select londiste.quote_fqname(table_name)"\ + " from londiste.table_info"\ " where queue_name = %s order by 1" % qname return self._ccache('known_table_list', q, 'londiste') @@ -519,7 +579,8 @@ class AdminConsole: if not self.cur_queue: return [] qname = skytools.quote_literal(self.cur_queue) - q = "select seq_name from londiste.seq_info"\ + q = "select londiste.quote_fqname(seq_name)"\ + " from londiste.seq_info"\ " where queue_name = %s order by 1" % qname return self._ccache('known_seq_list', q, 'londiste') @@ -682,9 +743,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`~!@#$%^&*()-=+[{]}\\|;:',<>/?") + #readline.set_completer_delims(" \t\n`~!@#$%^&*()-=+[{]}\\|;:',<>/?") hist_file = os.path.expanduser("~/.qadmin_history") try: @@ -751,8 +812,10 @@ class AdminConsole: c_pos = self.comp_cache.get('comp_pos') if c_pfx != pfx: c_list, c_pos = self.find_suggestions_real(pfx, params) + orig_pos = c_pos while c_pos < len(pfx) and pfx[c_pos].isspace(): c_pos += 1 + #print repr(pfx), orig_pos, c_pos self.comp_cache['comp_pfx'] = pfx self.comp_cache['comp_list'] = c_list self.comp_cache['comp_pos'] = c_pos @@ -771,32 +834,34 @@ class AdminConsole: # resync with readline offset if skip: res = [s[skip:] for s in res] - #print '\nfind_suggestions', repr(pfx), repr(curword), repr(res) + #print '\nfind_suggestions', repr(pfx), repr(curword), repr(res), repr(c_list) return res def find_suggestions_real(self, pfx, params): # find level node = top_level pos = 0 + xpos = 0 + xnode = node for typ, w, pos in self.sql_words(pfx): - if typ == 'ident': - w = normalize_any(w) + w = normalize_any(typ, w) node = node.get_next(typ, w, params) if not node: break + xnode = node + xpos = pos # find possible matches - if node: - return (node.get_completions(params), pos) + if xnode: + return (xnode.get_completions(params), xpos) else: - return ([], pos) + return ([], xpos) def exec_string(self, ln, eof = False): node = top_level params = {} for typ, w, pos in self.sql_words(ln): - if typ == 'ident': - w = normalize_any(w) + w = normalize_any(typ, w) #print repr(typ), repr(w) if typ == 'error': print 'syntax error 1:', repr(ln) @@ -1140,39 +1205,43 @@ class AdminConsole: curs = self.db.cursor() q = """select * from londiste.local_add_table(%s, %s)""" - curs.execute(q, [self.cur_queue, params['table']]) - - res = curs.fetchone() - print 'ADD_TABLE:', res[0], res[1] + for tbl in params['tables']: + curs.execute(q, [self.cur_queue, tbl]) + res = curs.fetchone() + print res[0], res[1] + print 'ADD_TABLE' def cmd_londiste_remove_table(self, params): """Remove table.""" curs = self.db.cursor() q = """select * from londiste.local_remove_table(%s, %s)""" - curs.execute(q, [self.cur_queue, params['table']]) - - res = curs.fetchone() - print 'REMOVE_TABLE:', res[0], res[1] + for tbl in params['tables']: + curs.execute(q, [self.cur_queue, tbl]) + res = curs.fetchone() + print res[0], res[1] + print 'REMOVE_TABLE' def cmd_londiste_add_seq(self, params): """Add seq.""" curs = self.db.cursor() q = """select * from londiste.local_add_seq(%s, %s)""" - curs.execute(q, [self.cur_queue, params['seq']]) - - res = curs.fetchone() - print 'ADD_SEQ:', res[0], res[1] + for seq in params['seqs']: + curs.execute(q, [self.cur_queue, seq]) + res = curs.fetchone() + print res[0], res[1] + print 'ADD_SEQ' def cmd_londiste_remove_seq(self, params): """Remove seq.""" curs = self.db.cursor() q = """select * from londiste.local_remove_seq(%s, %s)""" - curs.execute(q, [self.cur_queue, params['seq']]) - - res = curs.fetchone() + for seq in params['seqs']: + curs.execute(q, [self.cur_queue, seq]) + res = curs.fetchone() + print res[0], res[1] print 'REMOVE_SEQ:', res[0], res[1] def main(): |