def on_blob_save_clicked(self, button): d = self.emma.assign_once( "save dialog", gtk.FileChooserDialog, "save blob contents", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() if os.path.exists(filename): if not os.path.isfile(filename): show_message("save blob contents", "%s already exists and is not a file!" % filename) return if not confirm( "overwrite file?", "%s already exists! do you want to overwrite it?" % filename, self.emma.mainwindow): return b = self.tv.get_buffer() new_value = b.get_text(b.get_start_iter(), b.get_end_iter()).encode(self.emma.current_query.encoding, "ignore") try: fp = file(filename, "wb") fp.write(new_value) fp.close() except: show_message("save blob contents", "error writing query to file %s: %s" % (filename, sys.exc_value))
def on_blob_load_clicked(self, _): """ @param _: @return: """ d = self.emma.assign_once("load dialog", gtk.FileChooserDialog, "load blob contents", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() try: fp = file(filename, "rb") query_text = fp.read().decode(self.emma.current_query.encoding, "ignore") fp.close() except: show_message( "load blob contents", "loading blob contents from file %s: %s" % (filename, sys.exc_value)) return self.tv.get_buffer().set_text(query_text)
def on_blob_save_clicked(self, button): d = self.emma.assign_once("save dialog", gtk.FileChooserDialog, "save blob contents", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() if os.path.exists(filename): if not os.path.isfile(filename): show_message("save blob contents", "%s already exists and is not a file!" % filename) return if not confirm( "overwrite file?", "%s already exists! do you want to overwrite it?" % filename, self.emma.mainwindow): return b = self.tv.get_buffer() new_value = b.get_text(b.get_start_iter(), b.get_end_iter()).encode( self.emma.current_query.encoding, "ignore") try: fp = file(filename, "wb") fp.write(new_value) fp.close() except: show_message( "save blob contents", "error writing query to file %s: %s" % (filename, sys.exc_value))
def on_blob_load_clicked(self, _): """ @param _: @return: """ d = self.emma.assign_once( "load dialog", gtk.FileChooserDialog, "load blob contents", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() try: fp = file(filename, "rb") query_text = fp.read().decode(self.emma.current_query.encoding, "ignore") fp.close() except: show_message("load blob contents", "loading blob contents from file %s: %s" % (filename, sys.exc_value)) return self.tv.get_buffer().set_text(query_text)
def on_clicked(self, _): q = self.query path, column = q.treeview.get_cursor() if not path: return row_iter = q.model.get_iter(path) if q.append_iter \ and q.model.iter_is_valid(q.append_iter) \ and q.model.get_path(q.append_iter) == q.model.get_path(row_iter): q.append_iter = None q.apply_record.set_sensitive(False) else: table, where, field, value, row_iter = self.query.get_unique_where(q.last_source, path) if not table or not where: dialogs.show_message("delete record", "could not delete this record!?") return if self.query.current_host.__class__.__name__ == "sqlite_host": limit = "" else: limit = " limit 1" update_query = "delete from `%s` where %s%s" % (table, where, limit) if not self.query.current_host.query(update_query, encoding=q.encoding): return if not q.model.remove(row_iter): row_iter = q.model.get_iter_first() while row_iter: new = q.model.iter_next(row_iter) if new is None: break row_iter = new if row_iter: q.treeview.set_cursor(q.model.get_path(row_iter))
def on_kill_process(self, *args): path, column = self.treeview.get_cursor() if not path or not self.host: return _iter = self.model.get_iter(path) process_id = self.model.get_value(_iter, 0) if not self.host.query("kill %s" % process_id): dialogs.show_message("sorry", "there was an error while trying to kill process_id %s!" % process_id)
def on_kill_process(self, *args): path, column = self.treeview.get_cursor() if not path or not self.host: return _iter = self.model.get_iter(path) process_id = self.model.get_value(_iter, 0) if not self.host.query("kill %s" % process_id): dialogs.show_message( "sorry", "there was an error while trying to kill process_id %s!" % process_id)
def on_execute_query_from_disk_activate(self, button, filename=None): """ @param button: gtk.Button @param filename: str @return: """ if not self.connections_tv.current_host: show_message("execute query from disk", "no host selected!") return if not self.execute_query_from_disk_dialog: self.execute_query_from_disk_dialog = ExecuteQueryFromDisk(self) self.execute_query_from_disk_dialog.show()
def on_save_result_clicked(self, _): d = self.emma.assign_once( "save results dialog", gtk.FileChooserDialog, "save results", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() if os.path.exists(filename): if not os.path.isfile(filename): dialogs.show_message( "save results", "%s already exists and is not a file!" % filename ) return if not dialogs.confirm( "overwrite file?", "%s already exists! do you want to overwrite it?" % filename, self.emma.mainwindow): return q = self.query _iter = q.model.get_iter_first() indices = range(q.model.get_n_columns()) field_delim = self.emma.config.get("save_result_as_csv_delim") line_delim = self.emma.config.get("save_result_as_csv_line_delim") try: fp = file(filename, "wb") for search, replace in {"\\n": "\n", "\\r": "\r", "\\t": "\t", "\\0": "\0"}.iteritems(): field_delim = field_delim.replace(search, replace) line_delim = line_delim.replace(search, replace) while _iter: row = q.model.get(_iter, *indices) for field in row: value = field if value is None: value = "" fp.write(value.replace(field_delim, "\\" + field_delim)) fp.write(field_delim) fp.write(line_delim) _iter = q.model.iter_next(_iter) fp.close() except: dialogs.show_message( "save results", "error writing query to file %s: %s" % (filename, sys.exc_value) )
def run(self, query=None, again=False): """ :param query: :param again: :return: """ self.start_at_first_row.set_active(False) if not again or not self.entry.get_text(): self.entry.grab_focus() answer = self.window.run() self.window.hide() if not answer == gtk.RESPONSE_OK: return regex = self.entry.get_text() if self.case_sensitive.get_active(): regex = "(?i)" + regex query_model = query.model fields = query_model.get_n_columns() _start = query_model.get_iter_root() start_column_index = -1 start_path = None if not self.start_at_first_row.get_active(): start_path, start_column = query.treeview.get_cursor() if start_path: _start = query_model.get_iter(start_path) for k in range(fields): if query.treeview.get_column(k) == start_column: start_column_index = k break else: start_path = None while _start: for k in range(fields): query_model_value = query_model.get_value(_start, k) if query_model_value is None: continue if re.search(regex, query_model_value): path = query_model.get_path(_start) if start_path and start_path == path and k <= start_column_index: continue # skip! column = query.treeview.get_column(k) query.treeview.set_cursor(path, column) query.treeview.scroll_to_cell(path, column) query.treeview.grab_focus() return _start = query_model.iter_next(_start) dialogs.show_message( "local regex search", "sorry, no match found!\ntry to search from the beginning " "or execute a less restrictive query...")
def on_kill_process(self, _popup, _item): """ @type _item: gtk.ImageMenuItem @param _item: @type _popup: PopUpProcessList @param _popup: @return: """ if not _popup or not _item or not self.host: return path, _ = self.treeview.get_cursor() if not path: return _iter = self.model.get_iter(path) process_id = self.model.get_value(_iter, 0) if not self.host.query("kill %s" % process_id): dialogs.show_message( "sorry", "there was an error while trying to " "kill process_id %s!" % process_id)
def on_kill_process(self, _popup, _item): """ @type _item: gtk.ImageMenuItem @param _item: @type _popup: PopUpProcessList @param _popup: @return: """ if not _popup or not _item or not self.host: return path, _ = self.treeview.get_cursor() if not path: return _iter = self.model.get_iter(path) process_id = self.model.get_value(_iter, 0) if not self.host.query("kill %s" % process_id): dialogs.show_message("sorry", "there was an error while trying to " "kill process_id %s!" % process_id)
def on_clicked(self, _): """ @param _: @return: """ d = self.emma.assign_once( "save dialog", gtk.FileChooserDialog, "Save query", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() if os.path.exists(filename): if not os.path.isfile(filename): dialogs.show_message( "save query", "%s already exists and is not a file!" % filename ) return if not dialogs.confirm( "Overwrite file?", "%s already exists! Do you want to overwrite it?" % filename, self.emma.mainwindow ): return b = self.query.textview.get_buffer() query_text = b.get_text(b.get_start_iter(), b.get_end_iter()) try: fp = file(filename, "wb") fp.write(query_text) fp.close() except: dialogs.show_message( "Save Query", "Error writing query to file %s: %s" % (filename, sys.exc_value) )
def on_clicked(self, _): """ @param _: @return: """ d = self.emma.assign_once("save dialog", gtk.FileChooserDialog, "Save query", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() if os.path.exists(filename): if not os.path.isfile(filename): dialogs.show_message( "save query", "%s already exists and is not a file!" % filename) return if not dialogs.confirm( "Overwrite file?", "%s already exists! Do you want to overwrite it?" % filename, self.emma.mainwindow): return b = self.query.textview.get_buffer() query_text = b.get_text(b.get_start_iter(), b.get_end_iter()) try: fp = file(filename, "wb") fp.write(query_text) fp.close() except: dialogs.show_message( "Save Query", "Error writing query to file %s: %s" % (filename, sys.exc_value))
def on_clicked(self, _): """ @param _: @return: """ d = self.emma.assign_once("load dialog", gtk.FileChooserDialog, "Load query", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() try: sbuf = os.stat(filename) except: dialogs.show_message("Load query", "%s does not exists!" % filename) return if not S_ISREG(sbuf.st_mode): dialogs.show_message("Load query", "%s exists, but is not a file!" % filename) return size = sbuf.st_size _max = int( self.emma.config.get("ask_execute_query_from_disk_min_size")) if size > _max: if dialogs.confirm( "load query", """ <b>%s</b> is very big (<b>%.2fMB</b>)! opening it in the normal query-view may need a very long time! if you just want to execute this skript file without editing and syntax-highlighting, i can open this file using the <b>execute file from disk</b> function. <b>shall i do this?</b>""" % (filename, size / 1024.0 / 1000.0), self.emma.mainwindow): self.emma.on_execute_query_from_disk_activate(None, filename) return try: fp = file(filename, "rb") query_text = fp.read() fp.close() except: dialogs.show_message( "Load Query", "Error reading query from file %s: %s" % (filename, sys.exc_value)) return self.query.textview.get_buffer().set_text(query_text)
def on_clicked(self, _): """ @param _: @return: """ d = self.emma.assign_once( "load dialog", gtk.FileChooserDialog, "Load query", self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() try: sbuf = os.stat(filename) except: dialogs.show_message("Load query", "%s does not exists!" % filename) return if not S_ISREG(sbuf.st_mode): dialogs.show_message("Load query", "%s exists, but is not a file!" % filename) return size = sbuf.st_size _max = int(self.emma.config.get("ask_execute_query_from_disk_min_size")) if size > _max: if dialogs.confirm("load query", """ <b>%s</b> is very big (<b>%.2fMB</b>)! opening it in the normal query-view may need a very long time! if you just want to execute this skript file without editing and syntax-highlighting, i can open this file using the <b>execute file from disk</b> function. <b>shall i do this?</b>""" % (filename, size / 1024.0 / 1000.0), self.emma.mainwindow): self.emma.on_execute_query_from_disk_activate(None, filename) return try: fp = file(filename, "rb") query_text = fp.read() fp.close() except: dialogs.show_message( "Load Query", "Error reading query from file %s: %s" % (filename, sys.exc_value)) return self.query.textview.get_buffer().set_text(query_text)
def on_save_result_sql_clicked(self, _): title = "save results as sql insert script" d = self.emma.assign_once( "save results dialog", gtk.FileChooserDialog, title, self.emma.mainwindow, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) d.set_default_response(gtk.RESPONSE_ACCEPT) answer = d.run() d.hide() if not answer == gtk.RESPONSE_ACCEPT: return filename = d.get_filename() if os.path.exists(filename): if not os.path.isfile(filename): dialogs.show_message(title, "%s already exists and is not a file!" % filename) return if not dialogs.confirm( "overwrite file?", "%s already exists! " "do you want to overwrite it?" % filename, self.emma.mainwindow): return q = self.query _iter = q.model.get_iter_first() indices = range(q.model.get_n_columns()) # try to guess target table name from query table_name = "" query = self.query.last_source result = is_query_appendable(query) if result: table_list = result.group(7) table_list = table_list.replace(" join ", ",") table_list = re.sub( "(?i)(?:order[ \t\r\n]by.*|limit.*|group[ \r\n\t]by.*|order[ \r\n\t]by.*|where.*)", "", table_list) table_list = table_list.replace("`", "") tables = map(lambda s: s.strip(), table_list.split(",")) table_name = "_".join(tables) table_name = dialogs.input_dialog( title, "Please enter the name of the target table:", table_name, self.emma.mainwindow ) if table_name is None: return table_name = self.emma.current_host.escape_table(table_name) output_row = None try: fp = file(filename, "wb") fp.write("insert into %s values" % table_name) row_delim = "\n\t" while _iter: row = q.model.get(_iter, *indices) if not output_row: output_row = range(len(row)) for i, field in enumerate(row): if field is None: field = "NULL" elif not field.isdigit(): field = "'%s'" % q.current_host.escape(field.encode(q.encoding)) output_row[i] = field fp.write("%s(%s)" % (row_delim, ",".join(output_row))) row_delim = ",\n\t" _iter = q.model.iter_next(_iter) fp.write("\n;\n") fp.close() except: dialogs.show_message(title, "error writing to file %s: %s" % (filename, sys.exc_value))
def on_start_execute_from_disk_clicked(self, button): host = self.emma.connections_tv.current_host fc = self.glade.get_widget("eqfd_file_chooser") exclude = self.glade.get_widget("eqfd_exclude").get_active() exclude_regex = self.glade.get_widget("eqfd_exclude_entry").get_text() exclude = exclude and exclude_regex if exclude: try: exclude_regex = re.compile(exclude_regex, re.DOTALL) except: show_message( "execute query from disk", "error compiling your regular expression: %s" % sys.exc_value) return filename = fc.get_filename() try: sbuf = os.stat(filename) except: show_message("execute query from disk", "%s does not exists!" % filename) return if not S_ISREG(sbuf.st_mode): show_message("execute query from disk", "%s exists, but is not a regular file!" % filename) return size = sbuf.st_size try: fp = bz2.BZ2File(filename, "r", 1024 * 8) self.last_query_line = fp.readline() self.using_compression = True except: self.using_compression = False fp = None if fp is None: try: fp = file(filename, "rb") self.last_query_line = fp.readline() except: show_message( "execute query from disk", "error opening query from file %s: %s" % (filename, sys.exc_value)) return self.window.hide() start_line = self.glade.get_widget("eqfd_start_line").get_value() if start_line < 1: start_line = 1 ui = self.glade.get_widget("eqfd_update_interval") update_interval = ui.get_value() if update_interval == 0: update_interval = 2 p = self.glade.get_widget("execute_from_disk_progress") pb = self.glade.get_widget("exec_progress") offset_entry = self.glade.get_widget("edfq_offset") line_entry = self.glade.get_widget("eqfd_line") query_entry = self.glade.get_widget("eqfd_query") eta_label = self.glade.get_widget("eqfd_eta") append_to_log = self.glade.get_widget( "eqfd_append_to_log").get_active() stop_on_error = self.glade.get_widget( "eqfd_stop_on_error").get_active() limit_dbname = self.glade.get_widget("eqfd_db_entry").get_text() limit_db = self.glade.get_widget( "eqfd_limit_db").get_active() and limit_dbname != "" if limit_db: limit_re = re.compile("(?is)^use[ \r\n\t]+`?" + re.escape(limit_dbname) + "`?|^create database[^`]+`?" + re.escape(limit_dbname) + "`?") limit_end_re = re.compile( "(?is)^use[ \r\n\t]+`?.*`?|^create database") # last = 0 _start = time.time() def update_ui(force=False, offset=0): global last_update now = time.time() if not force and now - last_update < update_interval: return last_update = now pos = offset f = float(pos) / float(size) expired = now - _start if not self.using_compression and expired > 10: sr = float(expired) / float(pos) * float(size - pos) remaining = " (%.0fs remaining)" % sr eta_label.set_text("eta: %-19.19s" % datetime.datetime.fromtimestamp(now + sr)) else: remaining = "" query_entry.set_text(query[0:512]) offset_entry.set_text("%d" % pos) line_entry.set_text("%d" % current_line) if f > 1.0: f = 1.0 pb.set_fraction(f) pb_text = "%.2f%%%s" % (f * 100.0, remaining) pb.set_text(pb_text) self.emma.process_events() new_line = 1 current_line = _start query = "" p.show() while time.time() - _start < 0.10: update_ui(True) self.query_from_disk = True line_offset = 0 found_db = False while self.query_from_disk: current_line = new_line query, line_offset, new_line = self.read_one_query( fp, line_offset, current_line, update_ui, limit_db and not found_db, start_line) if current_line < start_line: current_line = start_line if query is None: break if limit_db: if not found_db: first = query.lstrip("\r\n\t ")[0:15].lower() if (first[0:3] == "use" or first == "create database") and limit_re.search(query): found_db = True else: if limit_end_re.search( query) and not limit_re.search(query): found_db = False update_ui(False, fp.tell()) if not limit_db or found_db: if exclude and exclude_regex.match(query): print "skipping query %r" % query[0:80] elif not host.query(query, True, append_to_log) and stop_on_error: show_message( "execute query from disk", "an error occoured. maybe remind the line number and press cancel to close this dialog!" ) self.query_from_disk = False break query = "" update_ui(True, fp.tell()) fp.close() if not self.query_from_disk: show_message( "execute query from disk", "aborted by user whish - click cancel again to close window") return else: show_message("execute query from disk", "done!") p.hide()
def on_clicked(self, _, query=None): """ @param _: @param query: @return: """ field_count = 0 if not query: b = self.query.textview.get_buffer() text = b.get_text(b.get_start_iter(), b.get_end_iter()) else: text = query self.query.current_host = host = self.query.current_host if not host: show_message( "error executing this query!", "could not execute query, because there is no selected host!" ) return self.query.current_db = self.query.current_db if self.query.current_db: host.select_database(self.query.current_db) elif host.current_db: if not confirm( "query without selected db", """warning: this query tab has no database selected but the host-connection already has the database '%s' selected. the author knows no way to deselect this database. do you want to continue?""" % host.current_db.name, self.emma.mainwindow): return update = False select = False self.query.editable = False # single popup self.query.toolbar.add_record.set_sensitive(False) self.query.toolbar.delete_record.set_sensitive(False) # per query buttons self.query.toolbar.add_record.set_sensitive(False) self.query.toolbar.delete_record.set_sensitive(False) self.query.toolbar.apply_record.set_sensitive(False) self.query.toolbar.local_search.set_sensitive(False) self.query.toolbar.remove_order.set_sensitive(False) self.query.toolbar.save_result_csv.set_sensitive(False) self.query.toolbar.save_result_sql.set_sensitive(False) affected_rows = 0 last_insert_id = 0 num_rows = 0 query_time = 0 download_time = 0 display_time = 0 query_count = 0 total_start = time.time() # cleanup last query model and treeview for col in self.query.treeview.get_columns(): self.query.treeview.remove_column(col) if self.query.model: self.query.model.clear() _start = 0 while _start < len(text): # search query end query_start, end = read_query(text, _start) if query_start is None: break thisquery = text[query_start:end] # print "about to execute query %r" % thisquery _start = end + 1 thisquery.strip(" \r\n\t;") if not thisquery: continue # empty query query_count += 1 query_hint = re.sub("[\n\r\t ]+", " ", thisquery[:40]) self.query.label.set_text("executing query %d %s..." % (query_count, query_hint)) self.query.label.window.process_updates(False) appendable = False appendable_result = is_query_appendable(thisquery) if appendable_result: appendable = True self.query.editable = self.query.is_query_editable(thisquery, appendable_result) # print "appendable: %s, editable: %s" % (appendable, self.query.editable) ret = host.query(thisquery, encoding=self.query.encoding) query_time += host.query_time if not ret: message = host.last_error self.emma.events.trigger('execute_query_error') # print "mysql error: %r" % (message, ) error(message) # message = "error at: %s" % host.last_error.replace( # "You have an error in your SQL syntax. " # "Check the manual that corresponds to your " # "MySQL server version for the right syntax to use near ", # "") # message = "error at: %s" % message.replace( # "You have an error in your SQL syntax; " # "check the manual that corresponds to your MySQL server " # "version for the right syntax to use near ", "") # # line_pos = 0 # pos = message.find("at line ") # if pos != -1: # line_no = int(message[pos + 8:]) # while 1: # line_no -= 1 # if line_no < 1: # break # p = thisquery.find("\n", line_pos) # if p == -1: # break # line_pos = p + 1 # # i = self.query.textview.get_buffer().get_iter_at_offset(query_start + line_pos) # # match = re.search("error at: '(.*)'", message, re.DOTALL) # if match and match.group(1): # # set focus and cursor! # # print "search for ->%s<-" % match.group(1) # pos = text.find( # match.group(1), # query_start + line_pos, # query_start + len(thisquery) # ) # if not pos == -1: # i.set_offset(pos) # else: # match = re.match("Unknown column '(.*?')", message) # if match: # # set focus and cursor! # pos = thisquery.find(match.group(1)) # if not pos == 1: # i.set_offset(query_start + pos) # # self.query.textview.get_buffer().place_cursor(i) # self.query.textview.scroll_to_iter(i, 0.0) # self.query.textview.grab_focus() self.query.label.set_text(re.sub("[\r\n\t ]+", " ", message)) return self.emma.events.trigger('execute_query_success') field_count = host.handle.field_count() if field_count == 0: # query without result update = True affected_rows += host.handle.affected_rows() last_insert_id = host.handle.insert_id() self.emma.events.trigger('execute_query_no_result') continue # query with result self.query.append_iter = None self.query.toolbar.local_search.set_sensitive(True) self.query.toolbar.add_record.set_sensitive(appendable) self.query.toolbar.delete_record.set_sensitive(self.query.editable) select = True self.query.last_source = thisquery # get sort order! sortable = True # todo current_order = get_order_from_query(thisquery) sens = False if len(current_order) > 0: sens = True self.query.toolbar.remove_order.set_sensitive(sens and sortable) sort_fields = dict() for c, o in current_order: sort_fields[c.lower()] = o self.query.label.set_text("downloading resultset...") self.query.label.window.process_updates(False) start_download = time.time() result = host.handle.store_result() download_time = time.time() - start_download if download_time < 0: download_time = 0 self.query.label.set_text("displaying resultset...") self.query.label.window.process_updates(False) # store field info self.query.result_info = result.describe() num_rows = result.num_rows() if num_rows == 0: self.emma.events.trigger('execute_query_empty') else: self.emma.events.trigger('execute_query_not_empty') for col in self.query.treeview.get_columns(): self.query.treeview.remove_column(col) columns = [gobject.TYPE_STRING] * field_count self.query.model = gtk.ListStore(*columns) self.query.treeview.set_model(self.query.model) self.query.treeview.set_rules_hint(True) self.query.treeview.set_headers_clickable(True) for i in range(field_count): title = self.query.result_info[i][0].replace("_", "__").replace("[\r\n\t ]+", " ") text_renderer = gtk.CellRendererText() if self.query.editable: text_renderer.set_property("editable", True) text_renderer.connect("edited", self.query.on_query_change_data, i) l = self.query.treeview.insert_column_with_data_func( -1, title, text_renderer, ResultCellRenders.render_mysql_string, i) col = self.query.treeview.get_column(l - 1) if self.emma.config.get_bool("result_view_column_resizable"): col.set_resizable(True) else: col.set_resizable(False) col.set_min_width(int(self.emma.config.get("result_view_column_width_min"))) col.set_max_width(int(self.emma.config.get("result_view_column_width_max"))) if sortable: col.set_clickable(True) col.connect("clicked", self.query.on_query_column_sort, i) # set sort indicator field_name = self.query.result_info[i][0].lower() try: sort_col = sort_fields[field_name] col.set_sort_indicator(True) if sort_col: col.set_sort_order(gtk.SORT_ASCENDING) else: col.set_sort_order(gtk.SORT_DESCENDING) except: col.set_sort_indicator(False) else: col.set_clickable(False) col.set_sort_indicator(False) cnt = 0 start_display = time.time() last_display = start_display for row in result.fetch_row(0): def to_string(f): """ To string Value of field @param f: @return: """ if isinstance(f, str): f = f.decode(self.query.encoding, "replace") elif f is None: pass else: f = str(f) return f self.query.model.append(map(to_string, row)) cnt += 1 if (cnt % 100) != 0: continue now = time.time() if (now - last_display) < 0.2: continue self.query.label.set_text("displayed %d rows..." % cnt) self.query.label.window.process_updates(False) last_display = now display_time = time.time() - start_display if display_time < 0: display_time = 0 result = [] if select: # there was a query with a result result.append("rows: %d" % num_rows) result.append("fields: %d" % field_count) self.query.toolbar.save_result_csv.set_sensitive(True) self.query.toolbar.save_result_sql.set_sensitive(True) if update: # there was a query without a result result.append("affected rows: %d" % affected_rows) result.append("insert_id: %d" % last_insert_id) total_time = time.time() - total_start result.append("| total time: %.2fs (query: %.2fs" % (total_time, query_time)) if select: result.append("download: %.2fs display: %.2fs" % (download_time, display_time)) result.append(")") self.query.label.set_text(' '.join(result)) self.emma.blob_view.tv.set_editable(self.query.editable) self.emma.blob_view.blob_update.set_sensitive(self.query.editable) self.emma.blob_view.blob_load.set_sensitive(self.query.editable) # todo update_buttons() gc.collect() return True
def on_start_execute_from_disk_clicked(self, button): host = self.emma.connections_tv.current_host fc = self.glade.get_widget("eqfd_file_chooser") exclude = self.glade.get_widget("eqfd_exclude").get_active() exclude_regex = self.glade.get_widget("eqfd_exclude_entry").get_text() exclude = exclude and exclude_regex if exclude: try: exclude_regex = re.compile(exclude_regex, re.DOTALL) except: show_message( "execute query from disk", "error compiling your regular expression: %s" % sys.exc_value) return filename = fc.get_filename() try: sbuf = os.stat(filename) except: show_message("execute query from disk", "%s does not exists!" % filename) return if not S_ISREG(sbuf.st_mode): show_message("execute query from disk", "%s exists, but is not a regular file!" % filename) return size = sbuf.st_size try: fp = bz2.BZ2File(filename, "r", 1024 * 8) self.last_query_line = fp.readline() self.using_compression = True except: self.using_compression = False fp = None if fp is None: try: fp = file(filename, "rb") self.last_query_line = fp.readline() except: show_message( "execute query from disk", "error opening query from file %s: %s" % (filename, sys.exc_value)) return self.window.hide() start_line = self.glade.get_widget("eqfd_start_line").get_value() if start_line < 1: start_line = 1 ui = self.glade.get_widget("eqfd_update_interval") update_interval = ui.get_value() if update_interval == 0: update_interval = 2 p = self.glade.get_widget("execute_from_disk_progress") pb = self.glade.get_widget("exec_progress") offset_entry = self.glade.get_widget("edfq_offset") line_entry = self.glade.get_widget("eqfd_line") query_entry = self.glade.get_widget("eqfd_query") eta_label = self.glade.get_widget("eqfd_eta") append_to_log = self.glade.get_widget("eqfd_append_to_log").get_active() stop_on_error = self.glade.get_widget("eqfd_stop_on_error").get_active() limit_dbname = self.glade.get_widget("eqfd_db_entry").get_text() limit_db = self.glade.get_widget("eqfd_limit_db").get_active() and limit_dbname != "" if limit_db: limit_re = re.compile("(?is)^use[ \r\n\t]+`?" + re.escape(limit_dbname) + "`?|^create database[^`]+`?" + re.escape(limit_dbname) + "`?") limit_end_re = re.compile("(?is)^use[ \r\n\t]+`?.*`?|^create database") # last = 0 _start = time.time() def update_ui(force=False, offset=0): global last_update now = time.time() if not force and now - last_update < update_interval: return last_update = now pos = offset f = float(pos) / float(size) expired = now - _start if not self.using_compression and expired > 10: sr = float(expired) / float(pos) * float(size - pos) remaining = " (%.0fs remaining)" % sr eta_label.set_text("eta: %-19.19s" % datetime.datetime.fromtimestamp(now + sr)) else: remaining = "" query_entry.set_text(query[0:512]) offset_entry.set_text("%d" % pos) line_entry.set_text("%d" % current_line) if f > 1.0: f = 1.0 pb.set_fraction(f) pb_text = "%.2f%%%s" % (f * 100.0, remaining) pb.set_text(pb_text) self.emma.process_events() new_line = 1 current_line = _start query = "" p.show() while time.time() - _start < 0.10: update_ui(True) self.query_from_disk = True line_offset = 0 found_db = False while self.query_from_disk: current_line = new_line query, line_offset, new_line = self.read_one_query( fp, line_offset, current_line, update_ui, limit_db and not found_db, start_line) if current_line < start_line: current_line = start_line if query is None: break if limit_db: if not found_db: first = query.lstrip("\r\n\t ")[0:15].lower() if (first[0:3] == "use" or first == "create database") and limit_re.search(query): found_db = True else: if limit_end_re.search(query) and not limit_re.search(query): found_db = False update_ui(False, fp.tell()) if not limit_db or found_db: if exclude and exclude_regex.match(query): print "skipping query %r" % query[0:80] elif not host.query(query, True, append_to_log) and stop_on_error: show_message( "execute query from disk", "an error occoured. maybe remind the line number and press cancel to close this dialog!") self.query_from_disk = False break query = "" update_ui(True, fp.tell()) fp.close() if not self.query_from_disk: show_message("execute query from disk", "aborted by user whish - click cancel again to close window") return else: show_message("execute query from disk", "done!") p.hide()
def on_template(self, button, t): """ :param button: :param t: :return: """ current_table = self.get_selected_table() if t.find("$table$") != -1: if not current_table: dialogs.show_message( "info", "no table selected!\nyou can't execute a template with $table$ in it, " "if you have no table selected!") return t = t.replace("$table$", self.current_host.escape_table(current_table.name)) pos = t.find("$primary_key$") if pos != -1: if not current_table: dialogs.show_message( "info", "no table selected!\nyou can't execute a template with $primary_key$ in it, " "if you have no table selected!") return if not current_table.fields: dialogs.show_message( "info", "sorry, can't execute this template, because table '%s' has no fields!" % current_table.name) return # is the next token desc or asc? result = re.search("(?i)[ \t\r\n]*(de|a)sc", t[pos:]) order_dir = "" if result: o = result.group(1).lower() if o == "a": order_dir = "asc" else: order_dir = "desc" replace = "" while 1: primary_key = "" for name in current_table.field_order: props = current_table.fields[name] if props[3] != "PRI": continue if primary_key: primary_key += " " + order_dir + ", " primary_key += self.current_host.escape_field(name) if primary_key: replace = primary_key break key = "" for name in current_table.field_order: props = current_table.fields[name] if props[3] != "UNI": continue if key: key += " " + order_dir + ", " key += self.current_host.escape_field(name) if key: replace = key break replace = self.current_host.escape_field(current_table.field_order[0]) break t = t.replace("$primary_key$", replace) if t.find("$field_conditions$") != -1: if not self.field_conditions_initialized: self.field_conditions_initialized = True self.fc_count = 4 self.fc_window = self.xml.get_widget("field_conditions") table = self.xml.get_widget("fc_table") table.resize(1 + self.fc_count, 4) self.fc_entry = [] self.fc_combobox = [] self.fc_op_combobox = [] self.fc_logic_combobox = [] for i in range(self.fc_count): self.fc_entry.append(gtk.Entry()) self.fc_entry[i].connect( "activate", lambda *e: self.fc_window.response(gtk.RESPONSE_OK) ) self.fc_combobox.append(gtk.combo_box_new_text()) self.fc_op_combobox.append(gtk.combo_box_new_text()) self.fc_op_combobox[i].append_text("=") self.fc_op_combobox[i].append_text("<") self.fc_op_combobox[i].append_text(">") self.fc_op_combobox[i].append_text("!=") self.fc_op_combobox[i].append_text("LIKE") self.fc_op_combobox[i].append_text("NOT LIKE") self.fc_op_combobox[i].append_text("ISNULL") self.fc_op_combobox[i].append_text("NOT ISNULL") if i: self.fc_logic_combobox.append(gtk.combo_box_new_text()) self.fc_logic_combobox[i - 1].append_text("disabled") self.fc_logic_combobox[i - 1].append_text("AND") self.fc_logic_combobox[i - 1].append_text("OR") table.attach(self.fc_logic_combobox[i - 1], 0, 1, i + 1, i + 2) self.fc_logic_combobox[i - 1].show() table.attach(self.fc_combobox[i], 1, 2, i + 1, i + 2) table.attach(self.fc_op_combobox[i], 2, 3, i + 1, i + 2) table.attach(self.fc_entry[i], 3, 4, i + 1, i + 2) self.fc_combobox[i].show() self.fc_op_combobox[i].show() self.fc_entry[i].show() if not current_table: dialogs.show_message( "info", "no table selected!\nyou can't execute a template with " "$field_conditions$ in it, if you have no table selected!") return last_field = [] for i in range(self.fc_count): last_field.append(self.fc_combobox[i].get_active_text()) self.fc_combobox[i].get_model().clear() if i: self.fc_logic_combobox[i - 1].set_active(0) fc = 0 for field_name in current_table.field_order: for k in range(self.fc_count): self.fc_combobox[k].append_text(field_name) if last_field[k] == field_name: self.fc_combobox[k].set_active(fc) fc += 1 if not self.fc_op_combobox[0].get_active_text(): self.fc_op_combobox[0].set_active(0) if not self.fc_combobox[0].get_active_text(): self.fc_combobox[0].set_active(0) answer = self.fc_window.run() self.fc_window.hide() if answer != gtk.RESPONSE_OK: return def field_operator_value(field, op, value): """ :param field: :param op: :param value: :return: """ if op == "ISNULL": return "isnull(`%s`)" % field if op == "NOT ISNULL": return "not isnull(`%s`)" % field eval_kw = "eval: " if value.startswith(eval_kw): return "`%s` %s %s" % (field, op, value[len(eval_kw):]) return "%s %s '%s'" % ( self.current_host.escape_field(field), op, self.current_host.escape(value) ) conditions = "%s" % ( field_operator_value( self.fc_combobox[0].get_active_text(), self.fc_op_combobox[0].get_active_text(), self.fc_entry[0].get_text() ) ) for i in range(1, self.fc_count): if self.fc_logic_combobox[i - 1].get_active_text() == "disabled" \ or self.fc_combobox[i].get_active_text() == "" \ or self.fc_op_combobox[i].get_active_text() == "": continue conditions += " %s %s" % ( self.fc_logic_combobox[i - 1].get_active_text(), field_operator_value( self.fc_combobox[i].get_active_text(), self.fc_op_combobox[i].get_active_text(), self.fc_entry[i].get_text() ) ) t = t.replace("$field_conditions$", conditions) try: new_order = self.stored_orders[self.current_host.current_db.name][current_table.name] # print "found stored order: %r" % (new_order,) query = t try: r = self.query_order_re except: r = self.query_order_re = re.compile(re_src_query_order) match = re.search(r, query) if match: before, order, after = match.groups() order = "" addition = "" else: match = re.search(re_src_after_order, query) if not match: before = query after = "" else: before = query[0:match.start()] after = match.group() addition = "\norder by\n\t" order = "" for col, o in new_order: if order: order += ",\n\t" order += self.current_host.escape_field(col) if not o: order += " desc" if order: new_query = ''.join([before, addition, order, after]) else: new_query = re.sub("(?i)order[ \r\n\t]+by[ \r\n\t]+", "", before + after) t = new_query except: pass self.events.trigger('execute_query')