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_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_toolbar_truncate_table(self, *args): if not confirm( "Truncate table", "Do You really want to TRUNCATE the <b>%s</b> table in database " "<b>%s</b> on <b>%s</b>?" % (self.name, self.db.name, self.db.host.name), None): return if self.db.query("truncate table `%s`" % self.name): if emma_instance: emma_instance.events.on_table_modified(self)
def on_toolbar_drop_table(self, *args): if not confirm( "Drop table", "do you really want to DROP the <b>%s</b> table in database " "<b>%s</b> on <b>%s</b>?" % (self.name, self.db.name, self.db.host.name), None): return if self.db.query("drop table `%s`" % self.name): if emma_instance: emma_instance.events.on_table_dropped(self)
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_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 on_drop_activate(self, *args): path, column = self.tv_fields.get_cursor() _iter = self.tv_fields_model.get_iter(path) _field_name = self.tv_fields_model.get_value(_iter, 2) if not confirm( "Drop field", "Do you really want to DROP field <b>%s</b> from table <b>%s</b>" " in database <b>%s</b> on <b>%s</b>?" % (_field_name, self.table.name, self.table.db.name, self.table.db.host.name), None): return self.table.drop_field(_field_name) self.refresh()
def on_drop_activate(self, *args): path, column = self.tv_fields.get_cursor() _iter = self.tv_fields_model.get_iter(path) _field_name = self.tv_fields_model.get_value(_iter, 2) if not confirm( "Drop field", "Do you really want to DROP field <b>%s</b> from table <b>%s</b>" " in database <b>%s</b> on <b>%s</b>?" % (_field_name, self.table.name, self.table.db.name, self.table.db.host.name), None, ): return self.table.drop_field(_field_name) self.refresh()
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( "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_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_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