Esempio n. 1
0
    def on_save_query_clicked(self, button):
        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.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))
Esempio n. 2
0
File: Emma.py Progetto: Zaffy/emma
 def on_execute_query_from_disk_activate(self, button, filename=None):
     if not self.connections_tv.current_host:
         dialogs.show_message("execute query from disk", "no host selected!")
         return
     if not self.execute_query_from_disk_dialog:
         self.execute_query_from_disk_dialog = dialogs.ExecuteQueryFromDisk(self)
     self.execute_query_from_disk_dialog.show()
Esempio n. 3
0
    def on_remember_order_clicked(self, button):
        query = self.query.last_source
        if not query:
            return None, None, None, None, None
        current_order = get_order_from_query(query)
        result = is_query_appendable(query)
        if not result:
            return None, None, None, None, None
        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(","))

        if len(tables) > 1:
            dialogs.show_message(
                "store table order",
                "can't store table order of multi-table queries!")
            return
        table = tables[0]

        print "---\ntable: %s order: %s" % (table, current_order)
        config_name = "stored_order_db_%s_table_%s" % (
            self.emma.current_host.current_db.name, table)
        print "config name %s" % config_name
        self.emma.config.config[config_name] = str(current_order)
        if not self.emma.current_host.current_db.name in self.emma.stored_orders:
            self.emma.stored_orders[
                self.emma.current_host.current_db.name] = {}
        self.emma.stored_orders[
            self.emma.current_host.current_db.name][table] = current_order
        self.emma.config.save()
Esempio n. 4
0
 def on_delete_record_tool_clicked(self, button):
     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))
Esempio n. 5
0
    def on_save_query_clicked(self, button):
        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.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))
Esempio n. 6
0
    def on_blob_load_clicked(self, button):
        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:
            dialogs.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)
Esempio n. 7
0
 def delete_record(self, event):
     selected_row = self.book_results_olv.GetSelectedObject()
     if selected_row is None:
         dialogs.show_message('No row selected!', 'Error')
         return
     controller.delete_record(self.session, selected_row.id)
     self.show_all_records()
Esempio n. 8
0
 def _is_valid_re(self, pattern, flags):
     """
     Check the validity of the regular expression and
     inform the user if it fails.
     """
     LOGGER.log()
     try:
         is_valid = bool(re.compile(pattern, flags))
     except re.error, re_error:
         is_valid = False
         title = 'Click Config: error in input'
         flag_text =  '\n    I (IGNORECASE)' * bool(flags & re.I)
         flag_text += '\n    M (MULTILINE)'  * bool(flags & re.M)
         flag_text += '\n    S (DOTALL)'     * bool(flags & re.S)
         flag_text += '\n    X (VERBOSE)'    * bool(flags & re.X)
         flag_text = flag_text or '\n    (None)'
         message = ('Invalid regular expression pattern.'
                    '\n\nError:\n    %s'
                    '\n\nPattern:\n    %s'
                    '\n\nFlags:%s'
                    % (re_error.message, pattern, flag_text))
         dialogs.show_message(title,
                              message,
                              Gtk.MessageType.ERROR,
                              self.window)
Esempio n. 9
0
File: Config.py Progetto: Zaffy/emma
    def save(self):
        if not os.path.exists(self.config_path):
            print "try to create config path %r" % self.config_path
            try:
                os.mkdir(self.config_path)
            except:
                dialogs.show_message("save config file",
                                     "could create config directory %r: %s" % (self.config_path, sys.exc_value))
                return

        filename = os.path.join(self.config_path, self.config_file)
        try:
            fp = file(filename, "w")
        except:
            dialogs.show_message("save config file", "could not open %s for writing: %s" % (filename, sys.exc_value))
            return

        keys = self.config.keys()
        keys.sort()
        for name in keys:
            if name.startswith("connection_"):
                continue
            value = self.config[name]
            fp.write("%s=%s\n" % (name, value))

        if self.emma:
            itr = self.emma.connections_tv.connections_model.get_iter_root()
            while itr:
                host = self.emma.connections_tv.connections_model.get_value(itr, 0)
                _str_to_write = "connection_%s=%s\n" % (host.name, host.get_connection_string())
                fp.write(_str_to_write)
                itr = self.emma.connections_tv.connections_model.iter_next(itr)
            fp.close()
Esempio n. 10
0
    def on_remember_order_clicked(self, button):
        query = self.query.last_source
        if not query:
            return None, None, None, None, None
        current_order = get_order_from_query(query)
        result = is_query_appendable(query)
        if not result:
            return None, None, None, None, None
        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(","))

        if len(tables) > 1:
            dialogs.show_message("store table order", "can't store table order of multi-table queries!")
            return
        table = tables[0]

        print "---\ntable: %s order: %s" % (table, current_order)
        config_name = "stored_order_db_%s_table_%s" % (self.emma.current_host.current_db.name, table)
        print "config name %s" % config_name
        self.emma.config.config[config_name] = str(current_order)
        if not self.emma.current_host.current_db.name in self.emma.stored_orders:
            self.emma.stored_orders[self.emma.current_host.current_db.name] = {}
        self.emma.stored_orders[self.emma.current_host.current_db.name][table] = current_order
        self.emma.config.save()
Esempio n. 11
0
 def on_execute_query_from_disk_activate(self, button, filename=None):
     if not self.current_host:
         dialogs.show_message("execute query from disk",
                              "no host selected!")
         return
     if not self.execute_query_from_disk_dialog:
         self.execute_query_from_disk_dialog = dialogs.ExecuteQueryFromDisk(
             self)
     self.execute_query_from_disk_dialog.show()
Esempio n. 12
0
 def delete_record(self, event):
     """
     Delete a record
     """
     selected_row = self.book_results_olv.GetSelectedObject()
     if selected_row is None:
         dialogs.show_message('No row selected!', 'Error')
         return
     with futures.ThreadPoolExecutor(max_workers=1) as executor:
         f = executor.submit(self.database.delete_record, selected_row.id)
         f.add_done_callback(self.show_all_records)
Esempio n. 13
0
    def edit_preservation(self, event):
        selected_row = self.skeleton_results_olv.GetSelectedObject()
        active_row = self.skeleton_results_olv.GetIndexOf(selected_row)
        if selected_row is None:
            dialogs.show_message('No record selected!', 'Error')
            return

        with dialogs.PreservationDialog(self.session, selected_row) as dlg:
            dlg.CenterOnScreen()
            dlg.ShowModal()

        self.skeleton_results_olv.SetFocus()
Esempio n. 14
0
    def edit_record(self, event):
        selected_row = self.book_results_olv.GetSelectedObject()
        if selected_row is None:
            dialogs.show_message('No row selected!', 'Error')
            return

        with dialogs.RecordDialog(self.session,
                                  selected_row,
                                  title="Modify",
                                  addRecord=False) as dlg:
            dlg.ShowModal()

        self.show_all_records()
Esempio n. 15
0
    def on_local_search_button_clicked(self, button, again=False):
        if not self.query.local_search.get_property("sensitive"):
            return

        query_view = self.query.treeview
        self.emma.local_search_start_at_first_row.set_active(False)
        if not again or not self.emma.local_search_entry.get_text():
            self.emma.local_search_entry.grab_focus()
            answer = self.emma.local_search_window.run()
            self.emma.local_search_window.hide()
            if not answer == gtk.RESPONSE_OK:
                return
        regex = self.emma.local_search_entry.get_text()
        if self.emma.local_search_case_sensitive.get_active():
            regex = "(?i)" + regex
        tm = self.query.model
        fields = tm.get_n_columns()
        _start = tm.get_iter_root()
        start_column_index = -1
        start_path = None
        if not self.emma.local_search_start_at_first_row.get_active():
            start_path, start_column = query_view.get_cursor()
            if start_path:
                _start = tm.get_iter(start_path)
                for k in range(fields):
                    if query_view.get_column(k) == start_column:
                        start_column_index = k
                        break
            else:
                start_path = None
        while _start:
            for k in range(fields):
                v = tm.get_value(_start, k)
                if v is None:
                    continue
                if re.search(regex, v):
                    path = tm.get_path(_start)
                    if start_path and start_path == path and k <= start_column_index:
                        continue  # skip!
                    column = query_view.get_column(k)
                    query_view.set_cursor(path, column)
                    query_view.scroll_to_cell(path, column)
                    query_view.grab_focus()
                    return
            _start = tm.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...")
Esempio n. 16
0
 def _get_new_name(self, name='', existing_names=(), desc=''):
     """Ask the user for a new name, and ensure it is new."""
     while 1:
         name = dialogs.ask_for_text(parent=self.window,
                                     title='Add %s' % desc,
                                     prompt='Enter a new name:',
                                     default=name)
         if name:
             name = name.strip()
         if name not in existing_names:
             break
         dialogs.show_message(title='Error adding %s name' % desc,
                              message='"%s" already exists.' % name,
                              type_=Gtk.MessageType.ERROR,
                              parent=self.window)
     return name
Esempio n. 17
0
    def edit_skeleton(self):
        selected_row = self.skeleton_results_olv.GetSelectedObject()
        active_row = self.skeleton_results_olv.GetIndexOf(selected_row)
        if selected_row is None:
            dialogs.show_message('No record selected!', 'Error')
            return

        with dialogs.RecordDialog(self.session,
                                  selected_row,
                                  title='Modify',
                                  addRecord=False) as dlg:
            dlg.CenterOnScreen()
            dlg.ShowModal()
            if dlg.result == 1:
                self.skeleton_results_olv.RefreshObject(selected_row)

        self.skeleton_results_olv.SetFocus()
Esempio n. 18
0
    def on_save_result_clicked(self, button):
        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))
Esempio n. 19
0
    def delete_record(self, event):
        """
        Delete a record
        """
        selected_row = self.skeleton_results_olv.GetSelectedObject()
        row_index = self.skeleton_results_olv.GetIndexOf(selected_row)
        if selected_row is None:
            dialogs.show_message('No record selected!', 'Error')
            return

        info = 'Delete current record?\n\nSite: {}\nLocation: {}\nSkeleton: {}'.format(
            selected_row.site, selected_row.location, selected_row.skeleton)
        if dialogs.ask_message(info, 'Delete record'):
            controller.delete_record(self.session, selected_row.skeleton_id)
            self.skeleton_results_olv.RemoveObject(selected_row)
            if row_index > 0:
                row_index -= 1

        self.skeleton_results_olv.Select(row_index)
        self.skeleton_results_olv.SetFocus()
Esempio n. 20
0
    def on_export_file(self, event):
        """ 
        export db to xlsx 
        """
        if self.session == None:
            dialogs.show_message('No data available for export.', 'Error')
            return

        wildcard = "XLSX files (*.xlsx)|*.xlsx"
        with wx.FileDialog(self,
                           "Export to XLSX",
                           wildcard=wildcard,
                           style=wx.FD_SAVE
                           | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_OK:
                self.xlsx_name = dialog.GetPath()
                result = controller.export_xlsx(self.session, self.xlsx_name)
                if result != '':
                    dialogs.show_message(result, 'Error')

        self.skeleton_results_olv.SetFocus()
Esempio n. 21
0
    def save(self):
        if not os.path.exists(self.config_path):
            print "try to create config path %r" % self.config_path
            try:
                os.mkdir(self.config_path)
            except:
                dialogs.show_message(
                    "save config file",
                    "could create config directory %r: %s" %
                    (self.config_path, sys.exc_value))
                return

        filename = os.path.join(self.config_path, self.config_file)
        try:
            fp = file(filename, "w")
        except:
            dialogs.show_message(
                "save config file", "could not open %s for writing: %s" %
                (filename, sys.exc_value))
            return

        keys = self.config.keys()
        keys.sort()
        for name in keys:
            if name.startswith("connection_"):
                continue
            value = self.config[name]
            fp.write("%s=%s\n" % (name, value))

        if self.emma:
            itr = self.emma.connections_tv.connections_model.get_iter_root()
            while itr:
                host = self.emma.connections_tv.connections_model.get_value(
                    itr, 0)
                _str_to_write = "connection_%s=%s\n" % (
                    host.name, host.get_connection_string())
                fp.write(_str_to_write)
                itr = self.emma.connections_tv.connections_model.iter_next(itr)
            fp.close()
Esempio n. 22
0
    def create_report(self, event):
        """ select report """
        dlg = wx.SingleChoiceDialog(self, 'Select report:', 'Create report', [
            'Skull report', 'Skull report - SVG', 'Inventory sheet',
            'Full report'
        ], wx.CHOICEDLG_STYLE)

        if dlg.ShowModal() == wx.ID_OK:
            selected = dlg.GetStringSelection()
        else:
            selected = ''

        dlg.Destroy()

        if selected == '':
            return

        if selected == 'Skull report':
            self.create_report_skull()
        elif selected == 'Skull report - SVG':
            self.create_report_skull_svg()
        else:
            dialogs.show_message(
                'Sorry, report "{}" not ready yet.'.format(selected), 'Error')
Esempio n. 23
0
 def on_delete_record_tool_clicked(self, button):
     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))
Esempio n. 24
0
    def on_load_query_clicked(self, button):
        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.textview.get_buffer().set_text(query_text)
Esempio n. 25
0
    def on_load_query_clicked(self, button):
        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.textview.get_buffer().set_text(query_text)
Esempio n. 26
0
    def on_execute_query_clicked(self, button=None, query=None):
        field_count = 0
        if not query:
            b = self.textview.get_buffer()
            text = b.get_text(b.get_start_iter(), b.get_end_iter())
        else:
            text = query

        self.current_host = host = self.current_host
        if not host:
            dialogs.show_message(
                "error executing this query!", "could not execute query, because there is no selected host!"
            )
            return

        self.current_db = self.current_db
        if self.current_db:
            host.select_database(self.current_db)
        elif host.current_db:
            if not dialogs.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.editable = False
        # single popup
        self.add_record.set_sensitive(False)
        self.delete_record.set_sensitive(False)
        # per query buttons
        self.add_record.set_sensitive(False)
        self.delete_record.set_sensitive(False)
        self.apply_record.set_sensitive(False)
        self.local_search.set_sensitive(False)
        self.remove_order.set_sensitive(False)
        self.save_result.set_sensitive(False)
        self.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.treeview.get_columns():
            self.treeview.remove_column(col)
        if self.model:
            self.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.label.set_text("executing query %d %s..." % (query_count, query_hint))
            self.label.window.process_updates(False)

            appendable = False
            appendable_result = is_query_appendable(thisquery)
            if appendable_result:
                appendable = True
                self.editable = self.is_query_editable(thisquery, appendable_result)
            print "appendable: %s, editable: %s" % (appendable, self.editable)

            ret = host.query(thisquery, encoding=self.encoding)
            query_time += host.query_time

            # if stop on error is enabled
            if not ret:
                print "mysql error: %r" % (host.last_error,)
                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.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.textview.get_buffer().place_cursor(i)
                self.textview.scroll_to_iter(i, 0.0)
                self.textview.grab_focus()
                self.label.set_text(re.sub("[\r\n\t ]+", " ", message))
                return

            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()
                continue

            # query with result
            self.append_iter = None
            self.local_search.set_sensitive(True)
            self.add_record.set_sensitive(appendable)
            self.delete_record.set_sensitive(self.editable)
            select = True
            self.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.remove_order.set_sensitive(sens and sortable)

            sort_fields = dict()
            for c, o in current_order:
                sort_fields[c.lower()] = o
            self.label.set_text("downloading resultset...")
            self.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.label.set_text("displaying resultset...")
            self.label.window.process_updates(False)

            # store field info
            self.result_info = result.describe()
            num_rows = result.num_rows()

            for col in self.treeview.get_columns():
                self.treeview.remove_column(col)

            columns = [gobject.TYPE_STRING] * field_count
            self.model = gtk.ListStore(*columns)
            self.treeview.set_model(self.model)
            self.treeview.set_rules_hint(True)
            self.treeview.set_headers_clickable(True)
            for i in range(field_count):
                title = self.result_info[i][0].replace("_", "__").replace("[\r\n\t ]+", " ")
                text_renderer = gtk.CellRendererText()
                if self.editable:
                    text_renderer.set_property("editable", True)
                    text_renderer.connect("edited", self.on_query_change_data, i)
                l = self.treeview.insert_column_with_data_func(
                    -1, title, text_renderer, widgets.ResultCellRenders.render_mysql_string, i
                )

                col = self.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.on_query_column_sort, i)
                    # set sort indicator
                    field_name = self.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):
                    if type(f) == str:
                        f = f.decode(self.encoding, "replace")
                    elif f is None:
                        pass
                    else:
                        f = str(f)
                    return f

                self.model.append(map(to_string, row))
                cnt += 1
                if not cnt % 100 == 0:
                    continue

                now = time.time()
                if (now - last_display) < 0.2:
                    continue

                self.label.set_text("displayed %d rows..." % cnt)
                self.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.save_result.set_sensitive(True)
            self.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.label.set_text(" ".join(result))
        self.emma.blob_view.tv.set_editable(self.editable)
        self.emma.blob_view.blob_update.set_sensitive(self.editable)
        self.emma.blob_view.blob_load.set_sensitive(self.editable)
        # todo update_buttons()
        gc.collect()
        return True
Esempio n. 27
0
    def on_start_execute_from_disk_clicked(self, button):
        host = self.emma.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:
                dialogs.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:
            dialogs.show_message("execute query from disk",
                                 "%s does not exists!" % filename)
            return
        if not S_ISREG(sbuf.st_mode):
            dialogs.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:
                dialogs.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:
                    dialogs.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
                    #print "exec", [query]
        query = ""
        update_ui(True, fp.tell())
        fp.close()
        if not self.query_from_disk:
            dialogs.show_message(
                "execute query from disk",
                "aborted by user whish - click cancel again to close window")
            return
        else:
            dialogs.show_message("execute query from disk", "done!")
        p.hide()
Esempio n. 28
0
    def create_report_skull_svg(self):
        """
        generating a skull picture
        """

        filename = ""
        wildcard = "SVG files (*.svg)|*.svg"
        with wx.FileDialog(self,
                           "Create a picture",
                           wildcard=wildcard,
                           style=wx.FD_SAVE
                           | wx.FD_OVERWRITE_PROMPT) as dialog:
            if dialog.ShowModal() == wx.ID_OK:
                filename = dialog.GetPath()

        if filename == "":
            return

        my_id = self.skeleton_results_olv.GetSelectedObject().skeleton_id
        rekord = controller.find_skeleton(self.session, my_id)
        if rekord == None:
            dialogs.show_message('No record was found', 'Error')
            return

        data = {}
        data['site'] = rekord.site
        data['location'] = rekord.location
        data['skeleton'] = rekord.skeleton
        data['observer'] = rekord.observer
        data['obs_date'] = rekord.obs_date
        data['frontal'] = rekord.frontal
        data['sphenoid'] = rekord.sphenoid
        data['mandible'] = rekord.mandible
        data['ethmoid'] = rekord.ethmoid
        data['parietal_l'] = rekord.parietal_l
        data['parietal_r'] = rekord.parietal_r
        data['nasal_l'] = rekord.nasal_l
        data['nasal_r'] = rekord.nasal_r
        data['palatine_l'] = rekord.palatine_l
        data['palatine_r'] = rekord.palatine_r
        data['thyroid'] = rekord.thyroid
        data['occipital'] = rekord.occipital
        data['maxilla_l'] = rekord.maxilla_l
        data['maxilla_r'] = rekord.maxilla_r
        data['lacrimal_l'] = rekord.lacrimal_l
        data['lacrimal_r'] = rekord.lacrimal_r
        data['hyoid'] = rekord.hyoid
        data['temporal_l'] = rekord.temporal_l
        data['temporal_r'] = rekord.temporal_r
        data['zygomatic_l'] = rekord.zygomatic_l
        data['zygomatic_r'] = rekord.zygomatic_r
        data['orbit_l'] = rekord.orbit_l
        data['orbit_r'] = rekord.orbit_r
        data['calotte'] = rekord.calotte

        report = SheetExport()
        result = report.export_skull_svg(filename, data)
        if result != '':
            dialogs.show_message(
                'Problems occurred during the creation of the picture:\n{}'.
                format(result), 'Error')

        self.skeleton_results_olv.SetFocus()
Esempio n. 29
0
    def on_template(self, button, t):
        current_table = self.get_selected_table()
        current_fc_table = current_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):
                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.current_query.on_execute_query_clicked(None, t)
Esempio n. 30
0
    def on_save_result_sql_clicked(self, button):
        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))
Esempio n. 31
0
    def on_execute_query_clicked(self, button=None, query=None):
        field_count = 0
        if not query:
            b = self.textview.get_buffer()
            text = b.get_text(b.get_start_iter(), b.get_end_iter())
        else:
            text = query

        self.current_host = host = self.current_host
        if not host:
            dialogs.show_message(
                "error executing this query!",
                "could not execute query, because there is no selected host!")
            return

        self.current_db = self.current_db
        if self.current_db:
            host.select_database(self.current_db)
        elif host.current_db:
            if not dialogs.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.editable = False
        # single popup
        self.add_record.set_sensitive(False)
        self.delete_record.set_sensitive(False)
        # per query buttons
        self.add_record.set_sensitive(False)
        self.delete_record.set_sensitive(False)
        self.apply_record.set_sensitive(False)
        self.local_search.set_sensitive(False)
        self.remove_order.set_sensitive(False)
        self.save_result.set_sensitive(False)
        self.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.treeview.get_columns():
            self.treeview.remove_column(col)
        if self.model:
            self.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.label.set_text("executing query %d %s..." %
                                (query_count, query_hint))
            self.label.window.process_updates(False)

            appendable = False
            appendable_result = is_query_appendable(thisquery)
            if appendable_result:
                appendable = True
                self.editable = self.is_query_editable(thisquery,
                                                       appendable_result)
            print "appendable: %s, editable: %s" % (appendable, self.editable)

            ret = host.query(thisquery, encoding=self.encoding)
            query_time += host.query_time

            # if stop on error is enabled
            if not ret:
                print "mysql error: %r" % (host.last_error, )
                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.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.textview.get_buffer().place_cursor(i)
                self.textview.scroll_to_iter(i, 0.0)
                self.textview.grab_focus()
                self.label.set_text(re.sub("[\r\n\t ]+", " ", message))
                return

            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()
                continue

            # query with result
            self.append_iter = None
            self.local_search.set_sensitive(True)
            self.add_record.set_sensitive(appendable)
            self.delete_record.set_sensitive(self.editable)
            select = True
            self.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.remove_order.set_sensitive(sens and sortable)

            sort_fields = dict()
            for c, o in current_order:
                sort_fields[c.lower()] = o
            self.label.set_text("downloading resultset...")
            self.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.label.set_text("displaying resultset...")
            self.label.window.process_updates(False)

            # store field info
            self.result_info = result.describe()
            num_rows = result.num_rows()

            for col in self.treeview.get_columns():
                self.treeview.remove_column(col)

            columns = [gobject.TYPE_STRING] * field_count
            self.model = gtk.ListStore(*columns)
            self.treeview.set_model(self.model)
            self.treeview.set_rules_hint(True)
            self.treeview.set_headers_clickable(True)
            for i in range(field_count):
                title = self.result_info[i][0].replace("_", "__").replace(
                    "[\r\n\t ]+", " ")
                text_renderer = gtk.CellRendererText()
                if self.editable:
                    text_renderer.set_property("editable", True)
                    text_renderer.connect("edited", self.on_query_change_data,
                                          i)
                l = self.treeview.insert_column_with_data_func(
                    -1, title, text_renderer,
                    widgets.ResultCellRenders.render_mysql_string, i)

                col = self.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.on_query_column_sort, i)
                    # set sort indicator
                    field_name = self.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):
                    if type(f) == str:
                        f = f.decode(self.encoding, "replace")
                    elif f is None:
                        pass
                    else:
                        f = str(f)
                    return f

                self.model.append(map(to_string, row))
                cnt += 1
                if not cnt % 100 == 0:
                    continue

                now = time.time()
                if (now - last_display) < 0.2:
                    continue

                self.label.set_text("displayed %d rows..." % cnt)
                self.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.save_result.set_sensitive(True)
            self.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.label.set_text(' '.join(result))
        self.emma.blob_view.tv.set_editable(self.editable)
        self.emma.blob_view.blob_update.set_sensitive(self.editable)
        self.emma.blob_view.blob_load.set_sensitive(self.editable)
        # todo update_buttons()
        gc.collect()
        return True
Esempio n. 32
0
File: Emma.py Progetto: Zaffy/emma
    def on_template(self, button, t):
        current_table = self.get_selected_table()
        current_fc_table = current_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):
                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.current_query.on_execute_query_clicked(None, t)