def edit(stdscr, cur, table, col_names, col_values, col, external): if external: val = edit_external(col_values[col_names.index(col)]) else: val = csui.get_string(stdscr, "New value for "+col+" column") (ands, largs) = make_limiter(col_names, col_values) query = "UPDATE %s SET %s=? WHERE %s" % (table, col, ands) args = [val, ] args.extend(largs) cur.Execute(query, args) logging.info(query)
def main_loop(api, stdscr, options): table = options.table selected_row = 0 selected_col = 0 page = 0 page_count = 0 col_names = [] last_query = None grid = None cur = api.conn.cursor() while True: #============================================================= # calculate useful things (height, width) = stdscr.getmaxyx() page_size = height-3 #============================================================= # get data query = "SELECT * FROM %s LIMIT %d,%d" % (table, page_size*page, page_size) if query != last_query: cur.execute("SELECT count(*) FROM %s" % table) page_count = math.ceil(float(cur.fetchone()[0]) / page_size) cur.execute("SELECT * FROM %s LIMIT %d OFFSET %d" % (table, page_size, page_size*page)) res = cur.fetchall() row_count = len(res) col_names = get_col_names(api, table) last_query = query col_width = (width-1)/len(col_names) #============================================================= # draw data # magic title = "%s -- Page %d/%d -- CSB %s" % ( table, page+1, page_count, version) csui.set_title(title) stdscr.refresh() # this makes things work and I don't know why # title titlebar = curses.newwin(1, width, 0, 0) titlebar.addstr(0, 0, "") titlebar.clrtoeol() titlebar.addstr(0, (width-len(title))/2, title) titlebar.refresh() # grid grid = curses.newwin(height-1, width, 1, 0) _w = str(col_width-1) col_fmt = " %-"+_w+"."+_w+"s" for colid, col in enumerate(col_names): grid.addstr(0, colid*col_width, col_fmt % col, curses.A_UNDERLINE) for rowid, row in enumerate(res): for colid, col in enumerate(row): if rowid == selected_row and colid == selected_col: grid.addstr(rowid+1, colid*col_width, rowsafe(col, col_width), curses.A_REVERSE) else: grid.addstr(rowid+1, colid*col_width, rowsafe(col, col_width)) grid.refresh() #============================================================= # input c = stdscr.getch() # global if c == ord('q'): if options.yes or csui.confirm(stdscr, "Commit and exit?"): break elif c == ord('x'): if options.yes or csui.confirm(stdscr, "Exit without saving?"): raise KeyboardInterrupt elif c == ord('t'): tables = get_tables(api) table = tables[csui.choose_option(stdscr, "Pick a table", tables)] # grid elif c == curses.KEY_UP: selected_row = selected_row - 1 elif c == curses.KEY_DOWN: selected_row = selected_row + 1 elif c == curses.KEY_LEFT: selected_col = selected_col - 1 elif c == curses.KEY_RIGHT: selected_col = selected_col + 1 elif c == curses.KEY_MOUSE: (mouseid, x, y, z, bstate) = curses.getmouse() selected_col = x/col_width selected_row = y-2 # page elif c == curses.KEY_PPAGE or c == ord('k'): page = page - 1 elif c == curses.KEY_NPAGE or c == ord('j'): page = page + 1 # display #elif c == ord('+'): col_width = col_width + 1 #elif c == ord('-'): col_width = col_width - 1 # editing elif c == ord('e'): edit( stdscr, cur, table, col_names, res[selected_row], col_names[selected_col], False) last_query = None elif c == ord('E'): edit( stdscr, cur, table, col_names, res[selected_row], col_names[selected_col], True) last_query = None elif c == curses.KEY_IC or c == ord('i'): vals = [] qs = [] for col in col_names: vals.append(csui.get_string(stdscr, col)) qs.append("?") query = "INSERT INTO %s(%s) VALUES (%s)" % (table, ", ".join(col_names), ", ".join(qs)) if options.yes or csui.confirm(stdscr, [query, str(vals)]): cur.Execute(query, vals) last_query = None elif c == curses.KEY_DC or c == ord('d'): (ands, args) = make_limiter(col_names, res[selected_row]) query = "DELETE FROM %s WHERE %s" % (table, ands) if options.yes or csui.confirm(stdscr, [query, str(args)]): cur.Execute(query, args) last_query = None elif c == curses.KEY_ENTER or c == ord('v'): csui.alert(stdscr, "Viewing Row", [str(a)+": "+unicode(b) for a, b in zip(col_names, res[selected_row])] ) elif c == ord('h') or c == ord('?'): csui.alert(stdscr, "Keys", [ "t - select table", "arrows - move over grid", "mouse1 - select cell", "pgup/dn - switch pages", #"+ / - - resize columns", "e - edit cell", "E - edit in external editor", "d - delete row", "v - view row", "h / ? - help", "q - commit and quit", "x - quit without committing", ]) #============================================================= # side effects of input if selected_row < 0: if page == 0: selected_row = 0 else: page = page - 1 selected_row = row_count-1 if selected_row > row_count - 1: if page == page_count - 1: selected_row = row_count-1 else: page = page + 1 selected_row = 0 selected_col = limit(selected_col, 0, len(col_names)-1) page = limit(page, 0, page_count-1) col_width = limit(col_width, 5, 100)