예제 #1
0
    def create_ui(self):
        #self.create_basic_ui("title_dashboard.png", "Dashboard")

        self._form_deactivated_conn = mforms.Form.main_form(
        ).add_deactivated_callback(self.form_deactivated)

        self.content = mforms.newScrollPanel(0)

        self.drawbox = RenderBox(self)
        self.canvas = Canvas(self.set_needs_repaint)
        self.drawbox.canvas = self.canvas
        self.drawbox.set_size(1024, 700)
        self.content.add(self.drawbox)

        self.widgets = []

        self.last_refresh_time = None

        #
        self.drawbox.variable_values = self.ctrl_be.server_variables
        server_version = Version.fromgrt(self.ctrl_be.target_version)
        GLOBAL_DASHBOARD_WIDGETS = GLOBAL_DASHBOARD_WIDGETS_NETWORK + GLOBAL_DASHBOARD_WIDGETS_MYSQL_PRE_80 + GLOBAL_DASHBOARD_WIDGETS_INNODB
        if server_version and server_version.is_supported_mysql_version_at_least(
                8, 0, 0):
            GLOBAL_DASHBOARD_WIDGETS = GLOBAL_DASHBOARD_WIDGETS_NETWORK + GLOBAL_DASHBOARD_WIDGETS_MYSQL_POST_80 + GLOBAL_DASHBOARD_WIDGETS_INNODB
        # create all widgets
        for caption, wclass, args, init, (
                calc,
                calc_expr), color, pos, hover_text in GLOBAL_DASHBOARD_WIDGETS:
            if caption:
                fig = TextFigure(caption)
                fig.set_text_color(0.3, 0.3, 0.3)
                fig.set_font_size(13)
                fig.set_font_bold(True)
                self.drawbox.add(fig)
                fig.move(pos[0], pos[1] - 20)

            w = wclass(calc(calc_expr) if calc else None, *args)
            self.drawbox.add(w)
            w.set_main_color(color)
            w.move(*pos)
            if hover_text:
                w.hover_text_template = hover_text

            if init:
                init_calc, init_expr = init
                w.init(
                    init_calc(init_expr).handle(self.ctrl_be.server_variables,
                                                None))

            self.widgets.append(w)

        self.refresh()
        self._refresh_tm = mforms.Utilities.add_timeout(
            self.ctrl_be.status_variable_poll_interval, self.refresh)

        self.ctrl_be.add_me_for_event("server_started", self)
        self.ctrl_be.add_me_for_event("server_stopped", self)

        return self.content
    def page_activated(self, advancing):
        WizardPage.page_activated(self, advancing)

        if advancing:
            supported_types = tuple(
                otype[0] for otype in
                self.main.plan.migrationSource.supportedObjectTypes)
            database_objects = {}
            ui_settings = {}
            for otype in supported_types:
                database_objects[
                    otype] = self.main.plan.migrationSource.selectedObjectsOfType(
                        otype)
                if otype != 'tables' and self.main.plan.migrationSource.rdbms.__id__ != 'com.mysql.rdbms.mysql':
                    ui_settings[otype] = {'group_selected': False}

            if self._scrollpanel:
                self.content.remove(self._scrollpanel)

            self._scrollpanel = mforms.newScrollPanel()
            self.db_selector = DatabaseObjectSelector(supported_types,
                                                      database_objects,
                                                      ui_settings)
            self._scrollpanel.add(self.db_selector)
            self.content.add(self._scrollpanel, True, True)
    def __init__(self, ctrl_be, server_profile, main_view):
        mforms.Box.__init__(self, True)
        self.set_managed()
        self.set_release_on_add()

        self.set_name("Server Status Main")

        self.ui_created = False

        self.set_spacing(24)

        self.ctrl_be = ctrl_be
        self.server_profile = server_profile
        self.main_view = main_view

        lbox = mforms.newBox(False)
        lbox.set_name("Server Status Left Side")
        self.add(lbox, True, True)

        self.connection_info = ConnectionInfo(self)
        self.connection_info.set_padding(24)
        lbox.add(self.connection_info, False, True)

        self.scrollbox = mforms.newScrollPanel(
            mforms.ScrollPanelDrawBackground)
        self.scrollbox.set_padding(24)
        self.scrollbox.set_name("Extra Server Info Section")

        self.content = mforms.newBox(False)
        self.content.set_padding(20)
        self.content.set_spacing(4)
        self.scrollbox.add(self.content)
        lbox.add(self.scrollbox, True, True)

        image = mforms.newImageBox()
        image.set_name("Server Status Separator")
        if self.server_profile.host_os == "linux":
            image.set_image(mforms.App.get().get_resource_path(
                "mysql-status-separator-linux.png"))
        else:
            image.set_image(mforms.App.get().get_resource_path(
                "mysql-status-separator.png"))
        image.set_image_align(mforms.MiddleCenter)
        self.add(image, False, True)

        self.status = wb_admin_monitor.WbAdminMonitor(server_profile,
                                                      self.ctrl_be)
        self.status.set_size(360, -1)
        self.status.set_padding(0, 24, 24, 24)
        self.add(self.status, False, True)

        self.controls = {}

        self.currently_started = None
        self.ctrl_be.add_me_for_event("server_started", self)
        self.ctrl_be.add_me_for_event("server_offline", self)
        self.ctrl_be.add_me_for_event("server_stopped", self)

        self.connection_info.update(self.ctrl_be)
    def create_ui(self):
      self.loading = True

      self.cfg_be = wb_admin_config_file_be.WbAdminConfigFileBE(self.server_profile, self.ctrl_be)

      sys_config_path = self.server_profile.config_file_path
      if sys_config_path is None:
        sys_config_path = ""
      self.file_name_ctrl.set_value(sys_config_path)
      self.section_ctrl.add_changed_callback(self.clear_and_load)
      try:
        self.myopts = self.cfg_be.get_possible_options()
        option_stats = self.cfg_be.get_option_set_stats()
        dprint_ex(1, "Options stats: '%s'" % str(option_stats))
        if option_stats and type(option_stats) is dict:
          added = option_stats.get("added", None)
          if added is not None and added < 10:
            user_selected_version = run_version_select_form(option_stats["version"])
            self.server_profile.set_server_version(".".join(map(lambda x: str(x), user_selected_version)))
            self.cfg_be.reload_possible_options()
            self.myopts = self.cfg_be.get_possible_options()
            option_stats = self.cfg_be.get_option_set_stats()
            dprint_ex(1, "Options stats after version correction: '%s'" % str(option_stats))
      except KeyError:
        Utilities.show_error("Error", "Wrong version '" + self.version + "'given to admin plugin", "Close", None, None)

      self.load_options_from_cfg()

      #build ordered list of pages. Initially only skeleton pages are created, means only names.
      # Values into pages will be load as soon as page is switched to.
      self.pages = {}
      for page_name, page_content in self.myopts.iteritems():
        self.pages[int(page_content['position'])] = Page(page_name, page_content) # False means page not created
      # page key is its position in UI. As we can have pages positions set like (1,2,4,5)
      # the position set needs to be sorted so pages appear in specified order
      page_positions = self.pages.keys()
      page_positions.sort()

      # Create dummy pages according to assigned position
      for page_pos in page_positions:
        page = self.pages[page_pos]
        page.panel = newScrollPanel(mforms.ScrollPanelNoFlags)
        self.tab_view.add_page(page.panel, page.page_name)

      if debug_level > 0:
        # Create file page
        page = Page("File", None)
        page.panel = newTextBox(mforms.BothScrollBars)
        page.set_update_cb(self.update_file_content_tab)
        self.pages[max(self.pages.keys()) + 1] = page
        self.tab_view.add_page(page.panel, page.page_name)

      # Create first page, so we display something from start
      self.create_page(1)
      self.loading = True # create_page resets loading flag

      self.tab_view.add_tab_changed_callback(self.tab_changed)

      self.loading = False
def waitSummary(editor):
    statement = editor.currentStatement
    if statement:
        before_rows = []
        after_rows = []

        rset = editor.owner.executeScript(
            "select * from performance_schema.events_waits_summary_by_thread_by_event_name as e join performance_schema.threads as t on e.thread_id=t.thread_id where t.processlist_id=connection_id()"
        )
        if rset:
            while rset[0].nextRow():
                row = []
                for i in range(7):
                    if i == 1:
                        row.append(rset[0].stringFieldValue(i))
                    else:
                        row.append(rset[0].intFieldValue(i))
                before_rows.append(row)

        editor.owner.executeScriptAndOutputToGrid(statement)

        rset = editor.owner.executeScript(
            "select * from performance_schema.events_waits_summary_by_thread_by_event_name as e join performance_schema.threads as t on e.thread_id=t.thread_id where t.processlist_id=connection_id()"
        )
        if rset:
            while rset[0].nextRow():
                row = []
                for i in range(7):
                    if i == 1:
                        row.append(rset[0].stringFieldValue(i))
                    else:
                        row.append(rset[0].intFieldValue(i))
                after_rows.append(row)
        tree = event_waits_summary_by_thread_by_event_name_to_tree(
            before_rows, after_rows)
        print tree
        import cairo
        import cairo_utils
        surf = cairo_utils.ImageSurface(cairo.CAIRO_FORMAT_ARGB32, 800, 800)
        c = cairo_utils.Context(surf)
        c.set_source_rgb(0, 0, 0)
        c.paint()
        chart = TreePieChart(tree, c)
        chart.plot()
        surf.write_to_png("/tmp/explain.png")

        view = mforms.newAppView(True, "QueryEditorView", False)
        scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        scroll.set_visible_scrollers(True, True)
        image = mforms.newImageBox()
        image.set_size(800, 800)
        scroll.add(image)
        image.set_image("/tmp/explain.png")
        view.add(scroll, True, True)
        dock = mforms.fromgrt(editor.resultDockingPoint)
        dock.dock_view(view, "", 0)
        dock.set_view_title(view, "Explain")

    return 0
    def create_ui(self):
        #self.create_basic_ui("title_dashboard.png", "Dashboard")


        self._form_deactivated_conn = mforms.Form.main_form().add_deactivated_callback(self.form_deactivated)


        self.content = mforms.newScrollPanel(0)

        self.drawbox = RenderBox(self)
        self.canvas = Canvas(self.set_needs_repaint)
        self.drawbox.canvas = self.canvas
        self.drawbox.set_size(1024, 700)
        self.content.add(self.drawbox)

        self.add(self.content, True, True)

        self.widgets = []
        
        self.last_refresh_time = None
        
        #
        self.drawbox.variable_values = self.ctrl_be.server_variables
        server_version = Version.fromgrt(self.ctrl_be.target_version)
        GLOBAL_DASHBOARD_WIDGETS = GLOBAL_DASHBOARD_WIDGETS_NETWORK + GLOBAL_DASHBOARD_WIDGETS_MYSQL_PRE_80 + GLOBAL_DASHBOARD_WIDGETS_INNODB
        if server_version and server_version.is_supported_mysql_version_at_least(8, 0, 0):
            GLOBAL_DASHBOARD_WIDGETS = GLOBAL_DASHBOARD_WIDGETS_NETWORK + GLOBAL_DASHBOARD_WIDGETS_MYSQL_POST_80 + GLOBAL_DASHBOARD_WIDGETS_INNODB
        # create all widgets
        for caption, wclass, args, init, (calc, calc_expr), color, pos, hover_text in GLOBAL_DASHBOARD_WIDGETS:
            if caption:
                fig = TextFigure(caption)
                fig.set_text_color(0.5, 0.5, 0.5)
                fig.set_font_size(11)
                fig.set_font_bold(True)
                self.drawbox.add(fig)
                fig.move(pos[0], pos[1] - 20)
        
            w = wclass(calc(calc_expr) if calc else None, *args)
            self.drawbox.add(w)
            w.set_main_color(color)
            w.move(*pos)
            if hover_text:
                w.hover_text_template = hover_text
            
            if init:
                init_calc, init_expr = init
                w.init(init_calc(init_expr).handle(self.ctrl_be.server_variables, None))

            self.widgets.append(w)


        self.refresh()
        self._refresh_tm = mforms.Utilities.add_timeout(self.ctrl_be.status_variable_poll_interval, self.refresh)
            
        self.ctrl_be.add_me_for_event("server_started", self)
        self.ctrl_be.add_me_for_event("server_stopped", self)
def waitSummary(editor):
    statement = editor.currentStatement
    if statement:
        before_rows = []
        after_rows = []

        rset = editor.owner.executeScript("select * from performance_schema.events_waits_summary_by_thread_by_event_name as e join performance_schema.threads as t on e.thread_id=t.thread_id where t.processlist_id=connection_id()")
        if rset:
            while rset[0].nextRow():
                row = []
                for i in range(7):
                    if i == 1:
                        row.append(rset[0].stringFieldValue(i))
                    else:
                        row.append(rset[0].intFieldValue(i))
                before_rows.append(row)

        editor.owner.executeScriptAndOutputToGrid(statement)

        rset = editor.owner.executeScript("select * from performance_schema.events_waits_summary_by_thread_by_event_name as e join performance_schema.threads as t on e.thread_id=t.thread_id where t.processlist_id=connection_id()")
        if rset:
            while rset[0].nextRow():
                row = []
                for i in range(7):
                    if i == 1:
                        row.append(rset[0].stringFieldValue(i))
                    else:
                        row.append(rset[0].intFieldValue(i))
                after_rows.append(row)
        tree = event_waits_summary_by_thread_by_event_name_to_tree(before_rows, after_rows)
        print tree
        import cairo
        import cairo_utils
        surf = cairo_utils.ImageSurface(cairo.CAIRO_FORMAT_ARGB32, 800, 800)
        c = cairo_utils.Context(surf)
        c.set_source_rgb(0,0,0)
        c.paint()
        chart = TreePieChart(tree, c)
        chart.plot()
        surf.write_to_png("/tmp/explain.png")

        view = mforms.newAppView(True, "QueryEditorView", False)
        scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        scroll.set_visible_scrollers(True, True)
        image = mforms.newImageBox()
        image.set_size(800, 800)
        scroll.add(image)
        image.set_image("/tmp/explain.png")
        view.add(scroll, True, True)
        dock = mforms.fromgrt(editor.resultDockingPoint)
        dock.dock_view(view, "", 0)
        dock.set_view_title(view, "Explain")
            
    return 0
예제 #8
0
    def create_ui(self):
        #self.create_basic_ui("title_dashboard.png", "Dashboard")

        self._form_deactivated_conn = mforms.Form.main_form(
        ).add_deactivated_callback(self.form_deactivated)

        self.content = mforms.newScrollPanel(0)

        self.drawbox = RenderBox(self)
        self.canvas = Canvas(self.set_needs_repaint)
        self.drawbox.canvas = self.canvas
        self.drawbox.set_size(1024, 700)
        self.content.add(self.drawbox)

        self.add(self.content, True, True)

        self.widgets = []

        self.last_refresh_time = None

        #
        self.drawbox.variable_values = self.ctrl_be.server_variables

        # create all widgets
        for caption, wclass, args, init, (
                calc,
                calc_expr), color, pos, hover_text in GLOBAL_DASHBOARD_WIDGETS:
            if caption:
                fig = TextFigure(caption)
                fig.set_text_color(0.5, 0.5, 0.5)
                fig.set_font_size(11)
                fig.set_font_bold(True)
                self.drawbox.add(fig)
                fig.move(pos[0], pos[1] - 20)

            w = wclass(calc(calc_expr) if calc else None, *args)
            self.drawbox.add(w)
            w.set_main_color(color)
            w.move(*pos)
            if hover_text:
                w.hover_text_template = hover_text

            if init:
                init_calc, init_expr = init
                w.init(
                    init_calc(init_expr).handle(self.ctrl_be.server_variables,
                                                None))

            self.widgets.append(w)

        self.refresh()
        self._refresh_tm = mforms.Utilities.add_timeout(
            self.ctrl_be.status_variable_poll_interval, self.refresh)
예제 #9
0
    def create_ui(self):
        self.loading = True

        self.cfg_be = wb_admin_config_file_be.WbAdminConfigFileBE(
            self.server_profile, self.ctrl_be)

        sys_config_path = self.server_profile.config_file_path
        if sys_config_path is None:
            sys_config_path = ""
        self.file_name_ctrl.set_value(sys_config_path)
        self.section_ctrl.add_changed_callback(self.clear_and_load)
        try:
            self.myopts = self.cfg_be.get_possible_options()
        except KeyError:
            Utilities.show_error(
                "Error",
                "Wrong version '" + self.version + "'given to admin plugin",
                "Close", None, None)

        self.load_options_from_cfg()

        #build ordered list of pages. Initially only skeleton pages are created, means only names.
        # Values into pages will be load as soon as page is switched to.
        self.pages = {}
        for page_name, page_content in self.myopts.iteritems():
            self.pages[int(page_content['position'])] = Page(
                page_name, page_content)  # False means page not created
        # page key is its position in UI. As we can have pages positions set like (1,2,4,5)
        # the position set needs to be sorted so pages appear in specified order
        page_positions = self.pages.keys()
        page_positions.sort()

        # Create dummy pages according to assigned position
        for page_pos in page_positions:
            page = self.pages[page_pos]
            page.panel = newScrollPanel(mforms.ScrollPanelNoFlags)
            self.tab_view.add_page(page.panel, page.page_name)

        if debug_level > 0:
            # Create file page
            page = Page("File", None)
            page.panel = newTextBox(mforms.BothScrollBars)
            page.set_update_cb(self.update_file_content_tab)
            self.pages[max(self.pages.keys()) + 1] = page
            self.tab_view.add_page(page.panel, page.page_name)

        # Create first page, so we display something from start
        self.create_page(1)
        self.loading = True  # create_page resets loading flag

        self.tab_view.add_tab_changed_callback(self.tab_changed)

        self.loading = False
    def __init__(self):
        VisualExplainViewer.__init__(self, False, "QueryEditorExplain", False)
        #tree = JSONTreeViewer()
        #tree.display_data(json)
        #view.add(tree, False, True)
        #tree.set_size(400, -1)

        self.toolbar = mforms.newToolbar(mforms.SecondaryToolBar)
        self.add(self.toolbar, False, True)

        self.scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        self.scroll.set_visible_scrollers(True, True)
        self.add(self.scroll, True, True)
    def __init__(self):
        VisualExplainViewer.__init__(self, False, "QueryEditorExplain", False)
        #tree = JSONTreeViewer()
        #tree.display_data(json)
        #view.add(tree, False, True)
        #tree.set_size(400, -1)

        self.toolbar = mforms.newToolbar(mforms.SecondaryToolBar)
        self.add(self.toolbar, False, True)

        self.scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        self.scroll.set_visible_scrollers(True, True)
        self.add(self.scroll, True, True)
    def __init__(self, ctrl_be, server_profile, main_view):
        mforms.Box.__init__(self, True)
        self.set_managed()
        self.set_release_on_add()

        self.ui_created = False

        self.set_spacing(24)

        self.ctrl_be = ctrl_be
        self.server_profile = server_profile
        self.main_view = main_view

        lbox = mforms.newBox(False)
        self.add(lbox, True, True)

        self.connection_info = ConnectionInfo()
        self.connection_info.set_padding(24)
        lbox.add(self.connection_info, False, True)

        self.scrollbox = mforms.newScrollPanel(mforms.ScrollPanelDrawBackground)
        self.scrollbox.set_padding(24)
        self.content = mforms.newBox(False)
        self.content.set_padding(20)
        self.content.set_spacing(4)
        self.scrollbox.add(self.content)
        lbox.add(self.scrollbox, True, True)

        image = mforms.newImageBox()
        if self.server_profile.host_os == "linux":
            image.set_image(mforms.App.get().get_resource_path("mysql-status-separator-linux.png"))
        else:
          image.set_image(mforms.App.get().get_resource_path("mysql-status-separator.png"))
        image.set_image_align(mforms.MiddleCenter)
        self.add(image, False, True)

        self.on_icon = mforms.App.get().get_resource_path("mysql-status-on.png")
        self.off_icon = mforms.App.get().get_resource_path("mysql-status-off.png")

        self.status = wb_admin_monitor.WbAdminMonitor(server_profile, self.ctrl_be)
        self.status.set_size(360, -1)
        self.status.set_padding(0, 24, 24, 24)
        self.add(self.status, False, False)

        self.controls = {}

        self.currently_started = None
        self.ctrl_be.add_me_for_event("server_started", self)
        self.ctrl_be.add_me_for_event("server_stopped", self)

        self.connection_info.update(self.ctrl_be)
예제 #13
0
파일: test3.py 프로젝트: dashiad/Siviglia
  def changedModel(self):
    if self.currentModel != None:
      self.currentModel.destroy();
    if self.tabView!=None:
      self.fieldContainer.remove(self.tabView)
      
    self.tabView=mforms.newTabView()
    
    curField = self.lbox.get_string_value() 
    i=0;    
    for curTable in self.schema.tables:      
      i=i+1      
      if curTable.name == curField:        
        self.fieldContainer.show(False)
        #Panel de modelo
        panel = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        generalView=mforms.newBox(True)
        panel.add(generalView)
        self.currentModel=ModelForm(generalView,curTable.name,curTable);
        self.tabView.add_page(panel,'General')
        #Panel de campos
        panel = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        fieldView=mforms.newBox(False)
        panel.add(fieldView)        
        self.fieldView=FieldForm(fieldView,curTable.name,curTable);
        self.tabView.add_page(panel,'Campos')
        #Panel de queries
        panel = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        queryView=mforms.newBox(False)
        panel.add(queryView)
        self.queryView=QueryForm(queryView,curTable.name,curTable);
        self.tabView.add_page(panel,'Queries')

        
        self.fieldContainer.show()
    self.tabView.set_active_tab(0)
    self.fieldContainer.add(self.tabView,True,True)    
    def page_activated(self, advancing):
        WizardPage.page_activated(self, advancing)

        if advancing:
            supported_types = tuple(otype[0] for otype in self.main.plan.migrationSource.supportedObjectTypes)
            database_objects = {}
            ui_settings = {}
            for otype in supported_types:
                database_objects[otype] = self.main.plan.migrationSource.selectedObjectsOfType(otype)
                if otype != 'tables' and self.main.plan.migrationSource.rdbms.__id__ != 'com.mysql.rdbms.mysql':
                    ui_settings[otype] = { 'group_selected' : False }

            if self._scrollpanel:
                self.content.remove(self._scrollpanel)

            self._scrollpanel = mforms.newScrollPanel()
            self.db_selector = DatabaseObjectSelector(supported_types, database_objects, ui_settings)
            self._scrollpanel.add(self.db_selector)
            self.content.add(self._scrollpanel, True, True)
예제 #15
0
    def __init__(self, ctrl_be, instance_info, main_view):
        mforms.Box.__init__(self, False)

        self.set_managed()
        self.set_release_on_add()

        self._instance_info = instance_info
        self._ctrl_be = ctrl_be
        self._main_view = main_view

        self._page_active = False
        self._error_screen_displayed = False

        self._page_header = mforms.newBox(False)

        if sys.platform.lower(
        ) == "darwin":  # No scrollbox on macOS as this is not needed and breaks selection.
            self._page_body = mforms.newBox(False)
        else:
            self._page_body = mforms.newScrollPanel()
        self._page_body.set_padding(8)

        self._page_footer = mforms.newBox(False)

        self.add(self._page_header, False, True)
        self.add(self._page_body, True, True)
        self.add(self._page_footer, False, True)

        self._header_contents = None
        self._body_contents = None
        self._footer_contents = None

        #if sys.platform.lower() != "darwin": # No scrollbox on macOS as this is not needed and breaks selection.
        #self._body_scroller = mforms.newScrollPanel()
        #self._page_body.add(self._body_scroller, True, True)

        self._validations = []
    def __init__(self, editor):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self.editor = editor

        self.set_spacing(8)
        self.set_padding(12)

        heading = mforms.newLabel("Table Maintenance Operations")
        heading.set_style(mforms.BigStyle)
        self.add(heading, False, True)

        help = mforms.newLabel("Select tables and click the operation you want to perform.\nNOTE: Some commands may require locking tables until completion,\nwhich may take a long time for large tables.")
        self.add(help, False, True)

        self.scroll = mforms.newScrollPanel(0)
        self.add(self.scroll, True, True)
        self.content = mforms.newBox(False)
        self.content.set_spacing(8)
        self.content.set_padding(12)
        self.scroll.add(self.content)

        self._buttons = []

        def make_command_box(callable, title, desc, tooltip, options = None, extra_options = None):
            l = mforms.newLabel(title)
            l.set_style(mforms.BoldStyle)
            self.content.add(l, False, True)

            l = mforms.newLabel(desc)
            self.content.add(l, False, True)

            if extra_options:
                self.content.add(extra_options, False, True)

            hb = mforms.newBox(True)
            hb.set_spacing(12)

            l = mforms.newImageBox()
            l.set_image(mforms.App.get().get_resource_path("mini_notice.png"))
            l.set_tooltip(tooltip)
            hb.add(l, False, True)

            for o in options:
                hb.add(o, False, True)

            btn = mforms.newButton()
            btn.add_clicked_callback(callable)
            btn.set_text(title.strip())
            hb.add_end(btn, False, True)

            self._buttons.append(btn)

            self.content.add(hb, False, True)

        self.analyze_local = mforms.newCheckBox()
        self.analyze_local.set_text("Don't write to BINLOG (local)")

        make_command_box(self.analyze_table, "Analyze Table",
                         """Analyzes and stores the key distribution for a table.
During the analysis, the table is locked with a read lock for InnoDB and MyISAM.""",
                         """With InnoDB tables, when you enable the innodb_stats_persistent option, you must run ANALYZE TABLE after loading substantial data into an InnoDB table, or creating a new index for one.

MySQL uses the stored key distribution to decide the order in which tables should be joined when you perform a join on something other than a constant. In addition, key distributions can be used when deciding which indexes to use for a specific table within a query.""",
                         [self.analyze_local])


        if editor.serverVersion.majorNumber > 5 or (editor.serverVersion.majorNumber == 5 and editor.serverVersion.minorNumber >= 6):
            extra_options = mforms.newBox(True)
            extra_options.set_spacing(4)

            self.optimize_ft_only = mforms.newCheckBox()
            self.optimize_ft_only.set_text("Optimize FULLTEXT only")
            self.optimize_ft_only.add_clicked_callback(self.optimize_ft_only_toggled)
            extra_options.add(self.optimize_ft_only, False, True)

            l = mforms.newLabel("")
            l.set_size(20, -1)
            extra_options.add(l, False, True)

            extra_options.add(mforms.newLabel("Number of words to optimize per run:"), False, True)
            self.optimize_ft_numwords = mforms.newTextEntry()
            self.optimize_ft_numwords.set_size(50, -1)
            self.optimize_ft_numwords.set_enabled(False)
            extra_options.add(self.optimize_ft_numwords, False, True)

            result = editor.executeManagementQuery("SHOW VARIABLES LIKE 'innodb_ft_num_word_optimize'", 0)
            if result and result.goToFirstRow():
                self.optimize_ft_numwords.set_value(result.stringFieldValue(1))
        else:
            extra_options = None
            self.optimize_ft_only = None

        self.optimize_local = mforms.newCheckBox()
        self.optimize_local.set_text("Don't write to BINLOG (local)")

        make_command_box(self.optimize_table, "\n\n"+"Optimize Table",
                         """Reorganizes the physical storage of table data and associated index data, 
to reduce storage space and improve I/O efficiency when accessing the table.""",
                         """The exact changes made to each table depend on the storage engine used by that table.

Use OPTIMIZE TABLE in these cases, depending on the type of table:

* After doing substantial insert, update, or delete operations on an InnoDB table that has its own .ibd file. The table and indexes are reorganized, and disk space can be reclaimed for use by the operating system.

* After doing substantial insert, update, or delete operations on columns that are part of a FULLTEXT index in an InnoDB table. Set the configuration option innodb_optimize_fulltext_only=1 first. To keep the index maintenance period to a reasonable time, set the innodb_ft_num_word_optimize option to specify how many words to update in the search index, and run Optimize Table until the search index is fully updated.""",
                         [self.optimize_local], extra_options)


        self.check_scan_opt = mforms.newSelector()
        self.check_scan_opt.add_items(["", "Quick", "Medium", "Extended", "For Upgrade"])

        self.check_fast_opt = mforms.newCheckBox()
        self.check_fast_opt.set_text("Fast")

        self.check_changed_opt = mforms.newCheckBox()
        self.check_changed_opt.set_text("Changed")

        options = [self.check_scan_opt, self.check_fast_opt, self.check_changed_opt]

        make_command_box(self.check_table, "\n\n"+"Check Table",
                         """CHECK TABLE checks a table or tables for errors. 
For MyISAM tables, the key statistics are updated as well.""",
                         """The FOR UPGRADE option checks whether the named tables are compatible with the current version of MySQL. With FOR UPGRADE, the server checks each table to determine whether there have been any incompatible changes in any of the table's data types or indexes since the table was created.
                             
Check Options:
- QUICK    Do not scan the rows to check for incorrect links. Applies to InnoDB and MyISAM tables and views.
- FAST    Check only tables that have not been closed properly. Applies only to MyISAM tables and views; ignored for InnoDB.
- CHANGED    Check only tables that have been changed since the last check or that have not been closed properly. Applies only to MyISAM tables and views; ignored for InnoDB.
- MEDIUM    Scan rows to verify that deleted links are valid. This also calculates a key checksum for the rows and verifies this with a calculated checksum for the keys. Applies only to MyISAM tables and views; ignored for InnoDB.
- EXTENDED    Do a full key lookup for all keys for each row. This ensures that the table is 100% consistent, but takes a long time. Applies only to MyISAM tables and views; ignored for InnoDB.""",
                         options)

        # The manual is full of scary warnings about this one, maybe better just leave user perform it by hand
#        make_command_box("\n"+"Repair Table",
#                         """""",
#                         """
#                             """)

        self.checksum_quick = mforms.newCheckBox()
        self.checksum_quick.set_text("Quick (if supported)")
        options = [self.checksum_quick]
        make_command_box(self.checksum_table, "\n\n"+"Checksum Table",
                         """CHECKSUM TABLE reports a checksum for the contents of a table.""",
                         """You can use this statement to verify that the contents are the same before and after a backup, rollback, or other operation that is intended to put the data back to a known state.""", options)
    def __init__(self, json):
        mforms.AppView.__init__(self, False, "QueryExplain", False)

        self.json_data = json
        self.toolbar = mforms.newToolBar(mforms.SecondaryToolBar)

        get_resource_path = mforms.App.get().get_resource_path

      
        #btn = newToolBarItem(mforms.SegmentedToggleItem)
        #btn.set_icon(get_resource_path("qe_resultset-tb-switcher_grid_off_mac.png"))
        #btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_grid_on_mac.png"))
        #self.toolbar.add_item(btn)

        #btn = newToolBarItem(mforms.SegmentedToggleItem)
        #btn.set_icon(get_resource_path("qe_resultset-tb-switcher_explain_off.png"))
        #btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_explain_on.png"))
        #self.toolbar.add_item(btn)

        #s = newToolBarItem(mforms.SeparatorItem)
        #self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("Spacing:")
        self.toolbar.add_item(l)
          
        btn = newToolBarItem(mforms.TextActionItem)
        btn.set_icon(get_resource_path("tiny_more_space.png"))
        btn.set_tooltip("Increase spacing between nodes.")
        btn.add_activated_callback(self.spacing_inc)
        self.toolbar.add_item(btn)

        btn = newToolBarItem(mforms.TextActionItem)
        btn.set_icon(get_resource_path("tiny_less_space.png"))
        btn.set_tooltip("Decrease spacing between nodes.")
        btn.add_activated_callback(self.spacing_dec)
        self.toolbar.add_item(btn)

        #s = newToolBarItem(mforms.SeparatorItem)
        #self.toolbar.add_item(s)
      
        #l = newToolBarItem(mforms.LabelItem)
        #l.set_text("Layout:")
        #self.toolbar.add_item(l)

        #btn = newToolBarItem(mforms.ToggleItem)
        #btn.set_icon(get_resource_path("tiny_align_h_middle.png"))
        #btn.add_activated_callback(lambda x:self.change_layout(True))
        #self.toolbar.add_item(btn)

        #btn = newToolBarItem(mforms.ToggleItem)
        #btn.set_icon(get_resource_path("tiny_align_v_middle.png"))
        #btn.add_activated_callback(lambda x:self.change_layout(False))
        #self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)
        
        btn = newToolBarItem(mforms.ActionItem)
        btn.set_icon(get_resource_path("tiny_saveas.png"))
        btn.add_activated_callback(self.save)
        btn.set_tooltip("Save image to an external file.")
        self.toolbar.add_item(btn)
        
    
        self.add(self.toolbar, False, True)
      
        self.scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        self.scroll.set_back_color("#ffffff")
        self.scroll.set_visible_scrollers(True, True)

        self.img = mforms.newImageBox()
        self.scroll.add(self.img)
            
        self.add(self.scroll, True, True)
예제 #18
0
    def create_ui(self):
        dprint_ex(4, "Enter")
        self.suspend_layout()

        self.create_basic_ui("title_connections.png", "Client Connections")

        if self.new_processlist():
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidthsPS", None)
        else:
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidths", None)
        if widths:
            column_widths = [int(i) for i in widths.split(",")]
        else:
            column_widths = None

        self.connection_box = mforms.newBox(True)
        self.connection_box.set_spacing(8)
        self.connection_list = newTreeNodeView(mforms.TreeDefault|mforms.TreeFlatList|mforms.TreeAltRowColors)
        self.connection_list.set_selection_mode(mforms.TreeSelectMultiple)
        self.connection_list.add_column_resized_callback(self.column_resized)
        for i, (field, type, caption, width) in enumerate(self.columns):
            if column_widths and i < len(column_widths):
                width = column_widths[i]
            self.connection_list.add_column(type, caption, width, False)

        self.connection_list.end_columns()
        self.connection_list.set_allow_sorting(True)
        
        self.connection_list.add_changed_callback(weakcb(self, "connection_selected"))

        self.connection_box.add(self.connection_list, True, True)

        info_table = mforms.newTable()
        info_table.set_row_count(2)
        info_table.set_column_count(5)
        info_table.set_row_spacing(4)
        info_table.set_column_spacing(20)

        info_table.add(self.create_labeled_info("Threads Connected:", "lbl_Threads_connected"),                     0, 1, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Running:", "lbl_Threads_running"),                          1, 2, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Created:", "lbl_Threads_created"),                         2, 3, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Cached:", "lbl_Threads_cached"),                           3, 4, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Rejected (over limit):", "lbl_Connection_errors_max_connections"), 4, 5, 0, 1, mforms.HFillFlag)

        info_table.add(self.create_labeled_info("Total Connections:", "lbl_Connections"),                           0, 1, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Connection Limit:", "lbl_max_connections"),                        1, 2, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Clients:", "lbl_Aborted_clients"),                         2, 3, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Connections:", "lbl_Aborted_connects"),                    3, 4, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Errors:", "lbl_errors", "tooltip_errors"),                         4, 5, 1, 2, mforms.HFillFlag)

        self.info_table = info_table
        self.add(info_table, False, True)

        #self.set_padding(8)
        self.add(self.connection_box, True, True)


        box = newBox(True)
        self.button_box = box
        self.add_end(box, False, True)

        box.set_spacing(12)
        
        refresh_button = newButton()
        refresh_button.set_text("Refresh")
        box.add_end(refresh_button, False, True)
        refresh_button.add_clicked_callback(weakcb(self, "refresh"))

        self.kill_button = newButton()
        self.kill_button.set_text("Kill Connection(s)")
        box.add_end(self.kill_button, False, True)
        self.kill_button.add_clicked_callback(weakcb(self, "kill_connection"))
        
        self.killq_button = newButton()
        self.killq_button.set_text("Kill Query(s)")
        box.add_end(self.killq_button, False, True)
        self.killq_button.add_clicked_callback(weakcb(self, "kill_query"))
        
        refresh_label = newLabel("Refresh Rate:")
        box.add(refresh_label, False, True)

        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self.connection_list.set_context_menu(self._menu)

        
        self.refresh_values = [0.5, 1, 2, 3, 4, 5, 10, 15, 30]
        self.refresh_values_size = len(self.refresh_values)
        
        self.refresh_selector = newSelector()
        self.refresh_selector.set_size(100,-1)
        
        for s in self.refresh_values:
            self.refresh_selector.add_item(str(s) + " seconds")
        
        self.refresh_selector.add_item("Don't Refresh")
        
        refresh_rate_index = grt.root.wb.options.options.get('Administrator:refresh_connections_rate_index', 9)
        self.refresh_selector.set_selected(refresh_rate_index)
        self.update_refresh_rate()
        self.refresh_selector.add_changed_callback(weakcb(self, "update_refresh_rate"))
        box.add(self.refresh_selector, False, True)

        self.check_box = newBox(True)
        self.check_box.set_spacing(12)

        self.hide_sleep_connections = newCheckBox()
        self.hide_sleep_connections.set_text('Hide sleeping connections')
        self.hide_sleep_connections.add_clicked_callback(self.refresh)
        self.hide_sleep_connections.set_tooltip('Remove connections in the Sleeping state from the connection list.')
        self.check_box.add(self.hide_sleep_connections, False, True)

        self.mdl_locks_page = None
        self._showing_extras = False
        if self.new_processlist():
            self.hide_background_threads = newCheckBox()
            self.hide_background_threads.set_active(True)
            self.hide_background_threads.set_text('Hide background threads')
            self.hide_background_threads.set_tooltip('Remove background threads (internal server threads) from the connection list.')
            self.hide_background_threads.add_clicked_callback(self.refresh)
            self.check_box.add(self.hide_background_threads, False, True)
            
            self.truncate_info = newCheckBox()
            self.truncate_info.set_active(True)
            self.truncate_info.set_text('Don\'t load full thread info')
            self.truncate_info.set_tooltip('Toggle whether to load the entire query information for all connections or just the first 255 characters.\nEnabling this can have a large impact in busy servers or server executing large INSERTs.')
            self.truncate_info.add_clicked_callback(self.refresh)
            self.check_box.add(self.truncate_info, False, True)

            # tab with some extra info, only available if PS exists
            self.extra_info_tab = mforms.newTabView(mforms.TabViewSystemStandard)
            self.extra_info_tab.set_size(350, -1)
            self.extra_info_tab.add_tab_changed_callback(self.extra_tab_changed)

            self.connection_details_scrollarea = mforms.newScrollPanel()
            self.connection_details = ConnectionDetailsPanel(self)
            self.connection_details_scrollarea.add(self.connection_details)
            self.details_page = self.extra_info_tab.add_page(self.connection_details_scrollarea, "Details")

            self.mdl_list_box = None
            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 7, 3):
                self.mdl_list_box_scrollarea = mforms.newScrollPanel()
                self.mdl_list_box = mforms.newBox(False)
                self.mdl_list_box_scrollarea.add(self.mdl_list_box)

                self.mdl_label = mforms.newLabel('Metadata locks (MDL) protect concurrent access to\nobject metadata (not table row/data locks)')
                self.mdl_list_box.add(self.mdl_label, False, True)

                label = mforms.newLabel("\nGranted Locks (and threads waiting on them)")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                label = mforms.newLabel("Locks this connection currently owns and\nconnections that are waiting for them.")
                label.set_style(mforms.SmallHelpTextStyle)
                self.mdl_list_box.add(label, False, True)

                self.mdl_list_held = mforms.newTreeNodeView(mforms.TreeAltRowColors)
                self.mdl_list_held.add_column(mforms.IconStringColumnType, "Object", 130, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Type", 100, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Duration", 100, False)
                self.mdl_list_held.end_columns()
                self.mdl_list_held.set_size(0, 100)
                self.mdl_list_box.add(self.mdl_list_held, True, True)

                label = mforms.newLabel("\nPending Locks")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                hbox = mforms.newBox(True)
                hbox.set_spacing(4)
                self.mdl_blocked_icon = mforms.newImageBox()
                self.mdl_blocked_icon.set_image(mforms.App.get().get_resource_path("message_warning.png"))
                hbox.add(self.mdl_blocked_icon, False, True)
                self.mdl_waiting_label = mforms.newLabel("Locks this connection is currently waiting for.")
                hbox.add(self.mdl_waiting_label, True, True)
                self.mdl_list_box.add(hbox, False, True)
                self.mdl_locks_page = self.extra_info_tab.add_page(self.mdl_list_box_scrollarea, "Locks")

            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 6, 0):
                self.attributes_list = mforms.newTreeNodeView(mforms.TreeFlatList|mforms.TreeAltRowColors)
                self.attributes_list.add_column(mforms.StringColumnType, "Attribute", 150, False)
                self.attributes_list.add_column(mforms.StringColumnType, "Value", 200, False)
                self.attributes_list.end_columns()
                self.attributes_page = self.extra_info_tab.add_page(self.attributes_list, "Attributes")

            self.connection_box.add(self.extra_info_tab, False, True)
            self.extra_info_tab.show(False)

            self.show_extras = newButton()
            self.show_extras.set_text('Show Details')
            self.show_extras.add_clicked_callback(self.toggle_extras)
            self.check_box.add_end(self.show_extras, False, True)

        self.add(self.check_box, False, True)
        
        self.resume_layout()
        
        self.connection_selected()
        
        dprint_ex(4, "Leave")
예제 #19
0
    def __init__(self, owner, json_text, context, server_version):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self._context = context

        get_resource_path = mforms.App.get().get_resource_path

        self.toolbar = mforms.newToolBar(mforms.SecondaryToolBar)
        self.toolbar.set_back_color("#ffffff")

        self.switcher_item = newToolBarItem(mforms.SelectorItem)
        self.toolbar.add_item(self.switcher_item)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("Display Info:")
        self.toolbar.add_item(l)

        item = newToolBarItem(mforms.SelectorItem)
        item.set_selector_items(["Read + Eval cost", "Data Read per Join"])
        item.add_activated_callback(self.display_cost)
        self.toolbar.add_item(item)
        cost_type_item = item

        # cost info was added in 5.7.2
        has_cost_info = server_version >= Version(5, 7)
        if not has_cost_info:
            item.set_enabled(False)


#item = newToolBarItem(mforms.SelectorItem)
#        item.set_selector_items(["Show Aggregated Costs", "Show Individual Costs"])
#        item.add_activated_callback(self.toggle_aggregated)
#        self.toolbar.add_item(item)

#btn = newToolBarItem(mforms.SegmentedToggleItem)
#btn.set_icon(get_resource_path("qe_resultset-tb-switcher_grid_off_mac.png"))
#btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_grid_on_mac.png"))
#self.toolbar.add_item(btn)

#btn = newToolBarItem(mforms.SegmentedToggleItem)
#btn.set_icon(get_resource_path("qe_resultset-tb-switcher_explain_off.png"))
#btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_explain_on.png"))
#self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        btn = newToolBarItem(mforms.ActionItem)
        btn.set_icon(get_resource_path("tiny_saveas.png"))
        btn.add_activated_callback(self.save)
        btn.set_tooltip("Save image to an external file.")
        self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("Overview:")
        self.toolbar.add_item(l)

        btn = newToolBarItem(mforms.ActionItem)
        btn.set_icon(
            get_resource_path("qe_sql-editor-explain-tb-overview.png"))
        btn.add_activated_callback(self.overview)
        btn.set_tooltip("Zoom out the diagram.")
        self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("View Source:")
        self.toolbar.add_item(l)

        btn = newToolBarItem(mforms.ToggleItem)
        btn.set_icon(get_resource_path("statusbar_output.png"))
        btn.set_alt_icon(get_resource_path("statusbar_output.png"))
        btn.add_activated_callback(self.switch_to_raw)
        btn.set_tooltip("View the raw JSON explain data.")
        self.toolbar.add_item(btn)

        self.add(self.toolbar, False, True)

        # Query Plan diagram
        self.scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        self.scroll.set_visible_scrollers(True, True)

        #self.img = mforms.newImageBox()
        self.drawbox = RenderBox(self._context, self.scroll)
        self.scroll.add(self.drawbox)

        self.drawbox.node_spacing = self.node_spacing
        self.drawbox.vertical = self.vertical
        self.add(self.scroll, True, True)

        self.display_cost(cost_type_item)

        # textbox to view the json data
        self._raw_explain = mforms.CodeEditor()
        self._raw_explain.set_value(json_text)
        self._raw_explain.set_language(mforms.LanguageJson)
        self._raw_explain.set_features(
            mforms.FeatureReadOnly | mforms.FeatureFolding, True)
        self.add(self._raw_explain, True, True)
        self._raw_explain.show(False)

        nc.add_observer(self.updateColors, "GNColorsChanged")
        backgroundColor = Color.getSystemColor(TextBackgroundColor)
        self.scroll.set_back_color(backgroundColor.to_html())
    def __init__(self, json):
        mforms.AppView.__init__(self, False, "QueryExplain", False)

        self.json_data = json
        self.toolbar = mforms.newToolBar(mforms.SecondaryToolBar)

        get_resource_path = mforms.App.get().get_resource_path

        #btn = newToolBarItem(mforms.SegmentedToggleItem)
        #btn.set_icon(get_resource_path("qe_resultset-tb-switcher_grid_off_mac.png"))
        #btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_grid_on_mac.png"))
        #self.toolbar.add_item(btn)

        #btn = newToolBarItem(mforms.SegmentedToggleItem)
        #btn.set_icon(get_resource_path("qe_resultset-tb-switcher_explain_off.png"))
        #btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_explain_on.png"))
        #self.toolbar.add_item(btn)

        #s = newToolBarItem(mforms.SeparatorItem)
        #self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("Spacing:")
        self.toolbar.add_item(l)

        btn = newToolBarItem(mforms.TextActionItem)
        btn.set_icon(get_resource_path("tiny_more_space.png"))
        btn.set_tooltip("Increase spacing between nodes.")
        btn.add_activated_callback(self.spacing_inc)
        self.toolbar.add_item(btn)

        btn = newToolBarItem(mforms.TextActionItem)
        btn.set_icon(get_resource_path("tiny_less_space.png"))
        btn.set_tooltip("Decrease spacing between nodes.")
        btn.add_activated_callback(self.spacing_dec)
        self.toolbar.add_item(btn)

        #s = newToolBarItem(mforms.SeparatorItem)
        #self.toolbar.add_item(s)

        #l = newToolBarItem(mforms.LabelItem)
        #l.set_text("Layout:")
        #self.toolbar.add_item(l)

        #btn = newToolBarItem(mforms.ToggleItem)
        #btn.set_icon(get_resource_path("tiny_align_h_middle.png"))
        #btn.add_activated_callback(lambda x:self.change_layout(True))
        #self.toolbar.add_item(btn)

        #btn = newToolBarItem(mforms.ToggleItem)
        #btn.set_icon(get_resource_path("tiny_align_v_middle.png"))
        #btn.add_activated_callback(lambda x:self.change_layout(False))
        #self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        btn = newToolBarItem(mforms.ActionItem)
        btn.set_icon(get_resource_path("tiny_saveas.png"))
        btn.add_activated_callback(self.save)
        btn.set_tooltip("Save image to an external file.")
        self.toolbar.add_item(btn)

        self.add(self.toolbar, False, True)

        self.scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        self.scroll.set_back_color("#ffffff")
        self.scroll.set_visible_scrollers(True, True)

        self.img = mforms.newImageBox()
        self.scroll.add(self.img)

        self.add(self.scroll, True, True)
    def create_ui(self):
        dprint_ex(4, "Enter")
        self.suspend_layout()

        self.create_basic_ui("title_connections.png", "Client Connections")

        if self.new_processlist():
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidthsPS", None)
        else:
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidths", None)
        if widths:
            column_widths = [int(i) for i in widths.split(",")]
        else:
            column_widths = None

        self.connection_box = mforms.newBox(True)
        self.connection_box.set_spacing(8)
        self.connection_list = newTreeNodeView(mforms.TreeDefault|mforms.TreeFlatList|mforms.TreeAltRowColors)
        self.connection_list.set_selection_mode(mforms.TreeSelectMultiple)
        self.connection_list.add_column_resized_callback(self.column_resized)
        for i, (field, type, caption, width) in enumerate(self.columns):
            if column_widths and i < len(column_widths):
                width = column_widths[i]
            self.connection_list.add_column(type, caption, width, False)

        self.connection_list.end_columns()
        self.connection_list.set_allow_sorting(True)
        
        self.connection_list.add_changed_callback(weakcb(self, "connection_selected"))

        self.connection_box.add(self.connection_list, True, True)

        info_table = mforms.newTable()
        info_table.set_row_count(2)
        info_table.set_column_count(5)
        info_table.set_row_spacing(4)
        info_table.set_column_spacing(20)

        info_table.add(self.create_labeled_info("Threads Connected:", "lbl_Threads_connected"),                     0, 1, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Running:", "lbl_Threads_running"),                          1, 2, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Created:", "lbl_Threads_created"),                         2, 3, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Cached:", "lbl_Threads_cached"),                           3, 4, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Rejected (over limit):", "lbl_Connection_errors_max_connections"), 4, 5, 0, 1, mforms.HFillFlag)

        info_table.add(self.create_labeled_info("Total Connections:", "lbl_Connections"),                           0, 1, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Connection Limit:", "lbl_max_connections"),                        1, 2, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Clients:", "lbl_Aborted_clients"),                         2, 3, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Connections:", "lbl_Aborted_connects"),                    3, 4, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Errors:", "lbl_errors", "tooltip_errors"),                         4, 5, 1, 2, mforms.HFillFlag)

        self.info_table = info_table
        self.add(info_table, False, True)

        #self.set_padding(8)
        self.add(self.connection_box, True, True)


        box = newBox(True)
        self.button_box = box
        self.add_end(box, False, True)

        box.set_spacing(12)
        
        refresh_button = newButton()
        refresh_button.set_text("Refresh")
        box.add_end(refresh_button, False, True)
        refresh_button.add_clicked_callback(weakcb(self, "refresh"))

        self.kill_button = newButton()
        self.kill_button.set_text("Kill Connection(s)")
        box.add_end(self.kill_button, False, True)
        self.kill_button.add_clicked_callback(weakcb(self, "kill_connection"))
        
        self.killq_button = newButton()
        self.killq_button.set_text("Kill Query(s)")
        box.add_end(self.killq_button, False, True)
        self.killq_button.add_clicked_callback(weakcb(self, "kill_query"))
        
        refresh_label = newLabel("Refresh Rate:")
        box.add(refresh_label, False, True)

        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self.connection_list.set_context_menu(self._menu)

        
        self.refresh_values = [0.5, 1, 2, 3, 4, 5, 10, 15, 30]
        self.refresh_values_size = len(self.refresh_values)
        
        self.refresh_selector = newSelector()
        self.refresh_selector.set_size(100,-1)
        
        for s in self.refresh_values:
            self.refresh_selector.add_item(str(s) + " seconds")
        
        self.refresh_selector.add_item("Don't Refresh")
        
        refresh_rate_index = grt.root.wb.options.options.get('Administrator:refresh_connections_rate_index', 9)
        self.refresh_selector.set_selected(refresh_rate_index)
        self.update_refresh_rate()
        self.refresh_selector.add_changed_callback(weakcb(self, "update_refresh_rate"))
        box.add(self.refresh_selector, False, True)

        self.check_box = newBox(True)
        self.check_box.set_spacing(12)

        self.hide_sleep_connections = newCheckBox()
        self.hide_sleep_connections.set_text('Hide sleeping connections')
        self.hide_sleep_connections.add_clicked_callback(self.refresh)
        self.hide_sleep_connections.set_tooltip('Remove connections in the Sleeping state from the connection list.')
        self.check_box.add(self.hide_sleep_connections, False, True)

        self.mdl_locks_page = None
        self._showing_extras = False
        if self.new_processlist():
            self.hide_background_threads = newCheckBox()
            self.hide_background_threads.set_active(True)
            self.hide_background_threads.set_text('Hide background threads')
            self.hide_background_threads.set_tooltip('Remove background threads (internal server threads) from the connection list.')
            self.hide_background_threads.add_clicked_callback(self.refresh)
            self.check_box.add(self.hide_background_threads, False, True)
            
            self.truncate_info = newCheckBox()
            self.truncate_info.set_active(True)
            self.truncate_info.set_text('Don\'t load full thread info')
            self.truncate_info.set_tooltip('Toggle whether to load the entire query information for all connections or just the first 255 characters.\nEnabling this can have a large impact in busy servers or server executing large INSERTs.')
            self.truncate_info.add_clicked_callback(self.refresh)
            self.check_box.add(self.truncate_info, False, True)

            # tab with some extra info, only available if PS exists
            self.extra_info_tab = mforms.newTabView(mforms.TabViewSystemStandard)
            self.extra_info_tab.set_size(350, -1)
            self.extra_info_tab.add_tab_changed_callback(self.extra_tab_changed)

            self.connection_details_scrollarea = mforms.newScrollPanel()
            self.connection_details = ConnectionDetailsPanel(self)
            self.connection_details_scrollarea.add(self.connection_details)
            self.details_page = self.extra_info_tab.add_page(self.connection_details_scrollarea, "Details")

            self.mdl_list_box = None
            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 7, 3):
                self.mdl_list_box_scrollarea = mforms.newScrollPanel()
                self.mdl_list_box = mforms.newBox(False)
                self.mdl_list_box_scrollarea.add(self.mdl_list_box)

                self.mdl_label = mforms.newLabel('Metadata locks (MDL) protect concurrent access to\nobject metadata (not table row/data locks)')
                self.mdl_list_box.add(self.mdl_label, False, True)

                label = mforms.newLabel("\nGranted Locks (and threads waiting on them)")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                label = mforms.newLabel("Locks this connection currently owns and\nconnections that are waiting for them.")
                label.set_style(mforms.SmallHelpTextStyle)
                self.mdl_list_box.add(label, False, True)

                self.mdl_list_held = mforms.newTreeNodeView(mforms.TreeAltRowColors)
                self.mdl_list_held.add_column(mforms.IconStringColumnType, "Object", 130, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Type", 100, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Duration", 100, False)
                self.mdl_list_held.end_columns()
                self.mdl_list_held.set_size(0, 100)
                self.mdl_list_box.add(self.mdl_list_held, True, True)

                label = mforms.newLabel("\nPending Locks")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                hbox = mforms.newBox(True)
                hbox.set_spacing(4)
                self.mdl_blocked_icon = mforms.newImageBox()
                self.mdl_blocked_icon.set_image(mforms.App.get().get_resource_path("message_warning.png"))
                hbox.add(self.mdl_blocked_icon, False, True)
                self.mdl_waiting_label = mforms.newLabel("Locks this connection is currently waiting for.")
                hbox.add(self.mdl_waiting_label, True, True)
                self.mdl_list_box.add(hbox, False, True)
                self.mdl_locks_page = self.extra_info_tab.add_page(self.mdl_list_box_scrollarea, "Locks")

            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 6, 0):
                self.attributes_list = mforms.newTreeNodeView(mforms.TreeFlatList|mforms.TreeAltRowColors)
                self.attributes_list.add_column(mforms.StringColumnType, "Attribute", 150, False)
                self.attributes_list.add_column(mforms.StringColumnType, "Value", 200, False)
                self.attributes_list.end_columns()
                self.attributes_page = self.extra_info_tab.add_page(self.attributes_list, "Attributes")

            self.connection_box.add(self.extra_info_tab, False, True)
            self.extra_info_tab.show(False)

            self.show_extras = newButton()
            self.show_extras.set_text('Show Details')
            self.show_extras.add_clicked_callback(self.toggle_extras)
            self.check_box.add_end(self.show_extras, False, True)

        self.add(self.check_box, False, True)
        
        self.resume_layout()
        
        self.connection_selected()
        
        dprint_ex(4, "Leave")
예제 #22
0
    def __init__(self, editor):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self.editor = editor

        self.set_spacing(8)
        self.set_padding(12)

        heading = mforms.newLabel("Table Maintenance Operations")
        heading.set_style(mforms.BigStyle)
        self.add(heading, False, True)

        help = mforms.newLabel(
            "Select tables and click the operation you want to perform.\nNOTE: Some commands may require locking tables until completion,\nwhich may take a long time for large tables."
        )
        self.add(help, False, True)

        self.scroll = mforms.newScrollPanel(0)
        self.add(self.scroll, True, True)
        self.content = mforms.newBox(False)
        self.content.set_spacing(8)
        self.content.set_padding(12)
        self.scroll.add(self.content)

        self._buttons = []

        def make_command_box(callable,
                             title,
                             desc,
                             tooltip,
                             options=None,
                             extra_options=None):
            l = mforms.newLabel(title)
            l.set_style(mforms.BoldStyle)
            self.content.add(l, False, True)

            l = mforms.newLabel(desc)
            self.content.add(l, False, True)

            if extra_options:
                self.content.add(extra_options, False, True)

            hb = mforms.newBox(True)
            hb.set_spacing(12)

            l = mforms.newImageBox()
            l.set_image(mforms.App.get().get_resource_path("mini_notice.png"))
            l.set_tooltip(tooltip)
            hb.add(l, False, True)

            for o in options:
                hb.add(o, False, True)

            btn = mforms.newButton()
            btn.add_clicked_callback(callable)
            btn.set_text(title.strip())
            hb.add_end(btn, False, True)

            self._buttons.append(btn)

            self.content.add(hb, False, True)

        self.analyze_local = mforms.newCheckBox()
        self.analyze_local.set_text("Don't write to BINLOG (local)")

        make_command_box(
            self.analyze_table, "Analyze Table",
            """Analyzes and stores the key distribution for a table.
During the analysis, the table is locked with a read lock for InnoDB and MyISAM.""",
            """With InnoDB tables, when you enable the innodb_stats_persistent option, you must run ANALYZE TABLE after loading substantial data into an InnoDB table, or creating a new index for one.

MySQL uses the stored key distribution to decide the order in which tables should be joined when you perform a join on something other than a constant. In addition, key distributions can be used when deciding which indexes to use for a specific table within a query.""",
            [self.analyze_local])

        if editor.serverVersion.majorNumber > 5 or (
                editor.serverVersion.majorNumber == 5
                and editor.serverVersion.minorNumber >= 6):
            extra_options = mforms.newBox(True)
            extra_options.set_spacing(4)

            self.optimize_ft_only = mforms.newCheckBox()
            self.optimize_ft_only.set_text("Optimize FULLTEXT only")
            self.optimize_ft_only.add_clicked_callback(
                self.optimize_ft_only_toggled)
            extra_options.add(self.optimize_ft_only, False, True)

            l = mforms.newLabel("")
            l.set_size(20, -1)
            extra_options.add(l, False, True)

            extra_options.add(
                mforms.newLabel("Number of words to optimize per run:"), False,
                True)
            self.optimize_ft_numwords = mforms.newTextEntry()
            self.optimize_ft_numwords.set_size(50, -1)
            self.optimize_ft_numwords.set_enabled(False)
            extra_options.add(self.optimize_ft_numwords, False, True)

            result = editor.executeManagementQuery(
                "SHOW VARIABLES LIKE 'innodb_ft_num_word_optimize'", 0)
            if result and result.goToFirstRow():
                self.optimize_ft_numwords.set_value(result.stringFieldValue(1))
        else:
            extra_options = None
            self.optimize_ft_only = None

        self.optimize_local = mforms.newCheckBox()
        self.optimize_local.set_text("Don't write to BINLOG (local)")

        make_command_box(
            self.optimize_table, "\n\n" + "Optimize Table",
            """Reorganizes the physical storage of table data and associated index data, 
to reduce storage space and improve I/O efficiency when accessing the table.""",
            """The exact changes made to each table depend on the storage engine used by that table.

Use OPTIMIZE TABLE in these cases, depending on the type of table:

* After doing substantial insert, update, or delete operations on an InnoDB table that has its own .ibd file. The table and indexes are reorganized, and disk space can be reclaimed for use by the operating system.

* After doing substantial insert, update, or delete operations on columns that are part of a FULLTEXT index in an InnoDB table. Set the configuration option innodb_optimize_fulltext_only=1 first. To keep the index maintenance period to a reasonable time, set the innodb_ft_num_word_optimize option to specify how many words to update in the search index, and run Optimize Table until the search index is fully updated.""",
            [self.optimize_local], extra_options)

        self.check_scan_opt = mforms.newSelector()
        self.check_scan_opt.add_items(
            ["", "Quick", "Medium", "Extended", "For Upgrade"])

        self.check_fast_opt = mforms.newCheckBox()
        self.check_fast_opt.set_text("Fast")

        self.check_changed_opt = mforms.newCheckBox()
        self.check_changed_opt.set_text("Changed")

        options = [
            self.check_scan_opt, self.check_fast_opt, self.check_changed_opt
        ]

        make_command_box(
            self.check_table, "\n\n" + "Check Table",
            """CHECK TABLE checks a table or tables for errors. 
For MyISAM tables, the key statistics are updated as well.""",
            """The FOR UPGRADE option checks whether the named tables are compatible with the current version of MySQL. With FOR UPGRADE, the server checks each table to determine whether there have been any incompatible changes in any of the table's data types or indexes since the table was created.
                             
Check Options:
- QUICK    Do not scan the rows to check for incorrect links. Applies to InnoDB and MyISAM tables and views.
- FAST    Check only tables that have not been closed properly. Applies only to MyISAM tables and views; ignored for InnoDB.
- CHANGED    Check only tables that have been changed since the last check or that have not been closed properly. Applies only to MyISAM tables and views; ignored for InnoDB.
- MEDIUM    Scan rows to verify that deleted links are valid. This also calculates a key checksum for the rows and verifies this with a calculated checksum for the keys. Applies only to MyISAM tables and views; ignored for InnoDB.
- EXTENDED    Do a full key lookup for all keys for each row. This ensures that the table is 100% consistent, but takes a long time. Applies only to MyISAM tables and views; ignored for InnoDB.""",
            options)

        # The manual is full of scary warnings about this one, maybe better just leave user perform it by hand
        #        make_command_box("\n"+"Repair Table",
        #                         """""",
        #                         """
        #                             """)

        self.checksum_quick = mforms.newCheckBox()
        self.checksum_quick.set_text("Quick (if supported)")
        options = [self.checksum_quick]
        make_command_box(
            self.checksum_table, "\n\n" + "Checksum Table",
            """CHECKSUM TABLE reports a checksum for the contents of a table.""",
            """You can use this statement to verify that the contents are the same before and after a backup, rollback, or other operation that is intended to put the data back to a known state.""",
            options)
예제 #23
0
    def create_ui(self):
        self.set_spacing(16)
        format_box = mforms.newBox(True)
        format_box.set_spacing(8)
        format_box.add(mforms.newLabel("Detected file format: %s" % self.input_file_type), False, True)
        if len(self.active_module.options) != 0:
            advanced_opts_btn = mforms.newButton(mforms.ToolButton)
            advanced_opts_btn.set_icon(mforms.App.get().get_resource_path("admin_option_file.png"))
            advanced_opts_btn.add_clicked_callback(lambda: self.optpanel.show(False) if self.optpanel.is_shown() else self.optpanel.show(True) )
            format_box.add(advanced_opts_btn, False, True)
        
        self.content.add(format_box, False, True)

        if len(self.active_module.options) != 0:
            self.optpanel = mforms.newPanel(mforms.TitledBoxPanel)
            self.optpanel.set_title("Options:")
            def set_text_entry(field, output):
                txt = field.get_string_value().encode('utf-8').strip()
                if len(txt) == 0:
                    operator.setitem(output, 'value', None)
                    mforms.Utilities.add_timeout(0.1, self.call_create_preview_table)
                elif len(txt) == 1:
                    operator.setitem(output, 'value', txt)
                    mforms.Utilities.add_timeout(0.1, self.call_create_preview_table)
                else:
                    field.set_value("")
                    mforms.Utilities.show_error("Import Wizard", "Due to the nature of this wizard, you can't use unicode characters in this place, as only one character is allowed.","Ok","","")


            def set_selector_entry(selector, output):
                operator.setitem(output, 'value', output['opts'][str(selector.get_string_value())])
                mforms.Utilities.add_timeout(0.1, self.call_create_preview_table)
            
            box = mforms.newBox(False)
            box.set_spacing(8)
            box.set_padding(8)
            for name, opts in self.active_module.options.iteritems():
                label_box = mforms.newBox(True)
                label_box.set_spacing(8)
                label_box.add(mforms.newLabel(opts['description']), False, True)
                if opts['type'] == 'text':
                    opt_val = mforms.newTextEntry()
                    opt_val.set_size(35, -1)
                    opt_val.set_value(opts['value'])
                    opt_val.add_changed_callback(lambda field = opt_val, output = opts: set_text_entry(field, output))
                    label_box.add_end(opt_val, False, True)
                    self.opts_mapping[name] = lambda val: opt_val.set_value(val)
                if opts['type'] == 'select':
                    opt_val = mforms.newSelector()
                    opt_val.set_size(75, -1)
                    opt_val.add_items([v for v in opts['opts']])
                    opt_val.set_selected(opts['opts'].values().index(opts['value']))
                    opt_val.add_changed_callback(lambda selector = opt_val, output = opts: set_selector_entry(selector, output))
                    self.opts_mapping[name] = lambda input, values =  opts['opts'].values(): opt_val.set_selected(values.index(input) if input in values else 0)
                    label_box.add_end(opt_val, False, True)
                box.add(label_box, False, True)
            self.optpanel.add(box)
            self.content.add(self.optpanel, False, True)
            self.optpanel.show(False)

        if self.input_file_type == 'csv':
            # We show encoding box only for csv as json can be only utf-8, utf-16 according to rfc
            self.encoding_box = mforms.newBox(True)
            self.encoding_box.set_spacing(16)
            self.encoding_box.add(mforms.newLabel("Encoding: "), False, True)
            self.encoding_sel = mforms.newSelector()
            self.encoding_sel.set_size(250, -1)
            self.encoding_box.add(self.encoding_sel, False, True)
        
            for i,e in enumerate(self.encoding_list):
                self.encoding_sel.add_item(e)
                if self.encoding_list[e] == 'utf-8':
                    self.encoding_sel.set_selected(i)
            self.encoding_sel.add_changed_callback(self.encoding_changed)
            self.content.add(self.encoding_box, False, True)
        
        self.table_preview_box = mforms.newBox(False)
        self.table_preview_box.set_spacing(16)
        self.preview_table = None
        self.content.add(self.table_preview_box, True, True)
        
        self.column_caption = mforms.newPanel(mforms.BorderedPanel)
        self.column_caption.set_title("Columns:")
        self.column_caption.set_size(-1, 100)
        self.column_scroll = mforms.newScrollPanel(0)
        self.column_caption.add(self.column_scroll)
        self.table_preview_box.add(self.column_caption, True, True)

        extra_opts = mforms.newBox(False)
        extra_opts.set_spacing(16)
        
        self.ds_box = mforms.newBox(True)
        self.ds_box.set_spacing(8)
        extra_opts.add(self.ds_box, False, True)
        
        self.df_box = mforms.newBox(True)
        self.df_box.set_spacing(8)
        extra_opts.add_end(self.df_box, False, True)
        
        self.ds_box.add(mforms.newLabel("Decimal Separator:"), False, True)
        self.ds_entry = mforms.newTextEntry()
        self.ds_entry.set_value('.')
        self.ds_entry.set_size(30, -1)
        self.ds_box.add(self.ds_entry, False, True)
        self.ds_box.show(False)
        
        self.df_box.add(self.make_label_with_tooltip("Date format: ", "Expects string pattern with the date format.\n"
                                                    "Default format is: %Y-%m-%d %H:%M:%S\n"
                                                    "\nCommon used options:\n"
                                                    "\t%d is the day number\n"
                                                    "\t%m is the month number\n"
                                                    "\t%y is the four digits year number\n"
                                                    "\t%H is the hour number\n"
                                                    "\t%M is the minute number\n"
                                                    "\t%S is the second number\n\n"
                                                    "More formats can be found under the following location:\n" 
                                                    "https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior"), False, True)
        self.df_entry = mforms.newTextEntry()
        self.df_entry.set_value("%Y-%m-%d %H:%M:%S")
        self.df_entry.set_size(200, -1)
        self.df_box.add(self.df_entry, False, True)
        self.df_box.show(False)
        
        self.content.add_end(extra_opts, False, True)