def __init__(self, main):
        WizardPage.__init__(self, main, "Target Creation Options")

        self.main.add_wizard_page(self, "ObjectMigration", "Target Creation Options")

        label = mforms.newLabel("Select options for the creation of the migrated schema in the target\nMySQL server and click [Next >] to execute.")
        self.content.add(label, False, True)

        panel = mforms.newPanel(mforms.TitledBoxPanel)
        panel.set_title("Schema Creation")
        self.content.add(panel, False, True)

        box = mforms.newBox(False)
        panel.add(box)
        box.set_padding(12)

        self._create_db = mforms.newCheckBox()
        self._create_db.set_text("Create schema in target RDBMS")
        box.add(self._create_db, False, True)

        # spacer
        box.add(mforms.newLabel(""), False, True)

        self._create_script = mforms.newCheckBox()
        self._create_script.set_text("Create a SQL script file")
        self._create_script.add_clicked_callback(self._toggle_sql_script)
        box.add(self._create_script, False, True)
        self._file_hbox = mforms.newBox(True)
        self._file_hbox.set_spacing(4)
        self._file_hbox.add(mforms.newLabel("Script File:"), False, True)
        self._create_script_file = mforms.newTextEntry()
        self._create_script_file.set_value(os.path.join(os.path.expanduser('~'), 'migration_script.sql'))
        self._file_hbox.add(self._create_script_file, True, True)
        button = mforms.newButton()
        button.set_text("Browse...")
        button.add_clicked_callback(self._browse_files)
        self._file_hbox.add(button, False, True)
        box.add(self._file_hbox, False, True)

        panel = mforms.newPanel(mforms.TitledBoxPanel)
        panel.set_title("Options")
        self.content.add(panel, False, True)

        box = mforms.newBox(False)
        panel.add(box)
        box.set_padding(12)
        box.set_spacing(8)

        self._keep_schema = mforms.newCheckBox()
        self._keep_schema.set_text("Keep schemas if they already exist. Objects that already exist will not be recreated or updated.")
        box.add(self._keep_schema, False, True)

        self._create_db.set_active(True)
        self._toggle_sql_script()
        self._check_file_duplicate = True
    def __init__(self, main):
        WizardPage.__init__(self, main, "Target Creation Options")

        self.main.add_wizard_page(self, "OBJECT MIGRATION", "Target Creation Options")

        label = mforms.newLabel("Select options for the creation of the migrated schema in the target\nMySQL server and click [Next >] to execute.")
        self.content.add(label, False, True)

        panel = mforms.newPanel(mforms.TitledBoxPanel)
        panel.set_title("Schema Creation")
        self.content.add(panel, False, True)

        box = mforms.newBox(False)
        panel.add(box)
        box.set_padding(12)

        self._create_db = mforms.newCheckBox()
        self._create_db.set_text("Create schema in target RDBMS")
        box.add(self._create_db, False, True)

        # spacer
        box.add(mforms.newLabel(""), False, True)

        self._create_script = mforms.newCheckBox()
        self._create_script.set_text("Create a SQL script file")
        self._create_script.add_clicked_callback(self._toggle_sql_script)
        box.add(self._create_script, False, True)
        self._file_hbox = mforms.newBox(True)
        self._file_hbox.set_spacing(4)
        self._file_hbox.add(mforms.newLabel("Script File:"), False, True)
        self._create_script_file = mforms.newTextEntry()
        self._create_script_file.set_value(os.path.join(os.path.expanduser('~'), 'migration_script.sql'))
        self._file_hbox.add(self._create_script_file, True, True)
        button = mforms.newButton()
        button.set_text("Browse...")
        button.add_clicked_callback(self._browse_files)
        self._file_hbox.add(button, False, True)
        box.add(self._file_hbox, False, True)

        panel = mforms.newPanel(mforms.TitledBoxPanel)
        panel.set_title("Options")
        self.content.add(panel, False, True)

        box = mforms.newBox(False)
        panel.add(box)
        box.set_padding(12)
        box.set_spacing(8)

        self._keep_schema = mforms.newCheckBox()
        self._keep_schema.set_text("Keep schemata if they already exist. Objects that already exist will not be recreated or updated.")
        box.add(self._keep_schema, False, True)

        self._create_db.set_active(True)
        self._toggle_sql_script()
        self._check_file_duplicate = True
Example #3
0
    def _add_script_checkbox_option(self, box, name, caption, path_caption,
                                    browser_caption):
        check = mforms.newCheckBox()
        check.set_text(caption)
        box.add(check, False, True)
        file_box = mforms.newBox(True)
        file_box.set_spacing(4)
        file_box.add(mforms.newLabel(path_caption), False, True)
        file_entry = mforms.newTextEntry()
        file_entry.add_changed_callback(lambda self=self, option=name: setattr(
            self, name + "_check_duplicate", True))
        file_box.add(file_entry, True, True)
        check.add_clicked_callback(lambda box=file_box, check=check: box.
                                   set_enabled(check.get_active()))
        button = mforms.newButton()
        button.set_text("Browse...")
        button.add_clicked_callback(lambda option=name, title=browser_caption:
                                    self._browse_files(option, title))
        file_box.add(button, False, True)
        box.add(file_box, False, True)
        file_box.set_enabled(False)

        setattr(self, name + "_check_duplicate", False)
        setattr(self, name + "_checkbox", check)
        setattr(self, name + "_entry", file_entry)
    def create_ui(self):
        # Main layout structure
        self.server_instance_box = mforms.newBox(False)
        self.server_instance_box.set_spacing(8)
        instance_label = mforms.newLabel('Target RDBMS Connection Parameters')
        instance_label.set_style(mforms.BoldStyle)
        self.server_instance_box.add(instance_label, False, True)

        # TODO: Enable the export to script option in future versions:
#        self.just_script_choice = mforms.newCheckBox()
#        self.just_script_choice.set_text('Do not use a live instance (SQL script output)')
#        self.just_script_choice.set_tooltip('Check this if you just want an output script to execute it later')
#        self.just_script_choice.add_clicked_callback(self.just_script_toggled)
#        self.server_instance_box.add(self.just_script_choice, False)

        # Add the view that corresponds to the selected RDBMS:
        self.panel = grt.classes.ui_db_ConnectPanel()
        self.panel.initialize(grt.root.wb.rdbmsMgmt)
        view = mforms.fromgrt(self.panel.view)
        self.server_instance_box.add(view, True, True)

        box = mforms.newBox(True)
        self._store_connection_check = mforms.newCheckBox()
        self._store_connection_check.set_text("Store connection for future usage as ")
        self._store_connection_check.add_clicked_callback(self._toggle_store_connection)
        box.add(self._store_connection_check, False, False)
        self._store_connection_entry = mforms.newTextEntry()
        box.add(self._store_connection_entry, True, True)
        self._store_connection_entry.set_enabled(False)

        self.server_instance_box.add(box, False, False)
        self.content.add(self.server_instance_box, True, True)

        self.advanced_button.set_text("Test Connection")
Example #5
0
 def addCheckbox(self, l, m , k):
   curBox=self.createBaseInput(l)
   input=mforms.newCheckBox()
   if m.has_key(k):
       input.set_active(m[k])
   curBox.add(input,False,True)        
   input.add_clicked_callback(lambda:self.changeBoolValue(input,m,k))
    def create_ui(self):
        self.content.set_padding(20)

        self.content.add(
            mforms.newLabel(
                'Select the schemas to copy to the destination server and click [Start Copy >] to start the process.'
            ), False, True)

        self.catalog_schemata = [
            full_name.partition('.')[-1]
            for full_name in self.main.plan.migrationSource.schemaNames
            if full_name not in SYSTEM_SCHEMAS
        ]
        self.schema_selector = DatabaseSchemaSelector(
            self.catalog_schemata,
            tree_checked_callback=self.update_next_button)
        self.content.add(self.schema_selector, True, True)

        self.innodb_switch = mforms.newCheckBox()
        self.innodb_switch.set_text('Migrate MyISAM tables to InnoDB')
        self.innodb_switch.set_active(True)
        self.content.add_end(self.innodb_switch, False)

        self.content.add_end(mforms.newLabel(''), False)

        self.next_button.set_text('Start Copy >')
        self.next_button.set_enabled(False)
    def column_selected(self):
        column = self.selected_column()
        if column:
            self.column_details.set_enabled(True)
            for c in self.flag_checkboxes:
                self.column_details.remove(c)
            self.flag_checkboxes = []

            if column.simpleType:
                for flag in column.simpleType.flags:
                    check = mforms.newCheckBox()
                    check.set_text(flag)
                    check.set_active(flag in column.flags)
                    self.column_details.add(check, False, True)
                    self.flag_checkboxes.append(check)
                    check.add_clicked_callback(lambda check=check, flag=flag:self.flag_checked(check, flag))
        
                if column.simpleType.group.name != "string" and not column.simpleType.name.lower().endswith("text"):
                    self.charset.set_selected(0)
                    self.charset.set_enabled(False)
                else:
                    self.charset.set_enabled(True)

            if not column.collationName:
                self.charset.set_selected(0)
            else:
                self.charset.set_value(column.collationName)
        else:
            self.charset.set_selected(0)
            self.column_details.set_enabled(False)
            for c in self.flag_checkboxes:
                self.column_details.remove(c)
            self.flag_checkboxes = []
 def create_options(self, box, options):
     optlist = []
     for option in options:
         cont = None
         if option.paramType == "boolean":
             opt = mforms.newCheckBox()
             opt.set_active(self.defaultValue == "1")
             box.add(opt, False, True)
             getter = opt.get_string_value
         elif option.paramType == "string":
             hbox = mforms.newBox(True)
             hbox.set_spacing(8)
             hbox.add(mforms.newLabel(option.caption), False, True)
             opt = mforms.newTextEntry()
             opt.set_value(option.defaultValue)
             hbox.add(opt, True, True)
             l = mforms.newLabel(option.description)
             l.set_style(mforms.SmallHelpTextStyle)
             hbox.add(l, False, True)
             box.add(hbox, False, True)
             cont = hbox
             getter = opt.get_string_value
         else:
             grt.send_error("MigrationWizard", "migrationOption() for source has an invalid parameter of type %s (%s)" % (option.paramType, option.name))
             continue
         optlist.append((cont or opt, option.name, getter))
     return optlist
Example #9
0
    def create_ui(self):
        self.content.set_padding(20)

        self.content.add(
            mforms.newLabel(
                'Select the schemas to copy to the destination server and click [Start Copy >] to start the process.'
            ), False, True)

        match_str = r"\%s\.\%s" % (self.main.plan.migrationSource._db_module.
                                   quoteIdentifier('(.+)\\'),
                                   self.main.plan.migrationSource._db_module.
                                   quoteIdentifier('(.+)\\'))

        self.catalog_schemata = [
            schema_name for catalog_name, schema_name in (
                re.match(match_str, full_name).groups() for full_name in [
                    x for x in self.main.plan.migrationSource.schemaNames
                    if x not in SYSTEM_SCHEMAS
                ])
        ]

        self.schema_selector = DatabaseSchemaSelector(
            self.catalog_schemata,
            tree_checked_callback=self.update_next_button)
        self.content.add(self.schema_selector, True, True)

        self.innodb_switch = mforms.newCheckBox()
        self.innodb_switch.set_text('Migrate MyISAM tables to InnoDB')
        self.innodb_switch.set_active(True)
        self.content.add_end(self.innodb_switch, False)

        self.content.add_end(mforms.newLabel(''), False)

        self.next_button.set_text('Start Copy >')
        self.next_button.set_enabled(False)
Example #10
0
 def create_options(self, box, options):
     optlist = []
     for option in options:
         cont = None
         if option.paramType == "boolean":
             opt = mforms.newCheckBox()
             opt.set_active(self.defaultValue == "1")
             box.add(opt, False, True)
             getter = opt.get_string_value
         elif option.paramType == "string":
             hbox = mforms.newBox(True)
             hbox.set_spacing(8)
             hbox.add(mforms.newLabel(option.caption), False, True)
             opt = mforms.newTextEntry()
             opt.set_value(option.defaultValue)
             hbox.add(opt, True, True)
             l = mforms.newLabel(option.description)
             l.set_style(mforms.SmallHelpTextStyle)
             hbox.add(l, False, True)
             box.add(hbox, False, True)
             cont = hbox
             getter = opt.get_string_value
         else:
             grt.send_error("MigrationWizard", "migrationOption() for source has an invalid parameter of type %s (%s)" % (option.paramType, option.name))
             continue
         optlist.append((cont or opt, option.name, getter))
     return optlist
    def create_ui(self):
        # Main layout structure
        self.server_instance_box = mforms.newBox(False)
        self.server_instance_box.set_spacing(8)
        instance_label = mforms.newLabel('Target RDBMS Connection Parameters')
        instance_label.set_style(mforms.BoldStyle)
        self.server_instance_box.add(instance_label, False, True)

        # TODO: Enable the export to script option in future versions:
#        self.just_script_choice = mforms.newCheckBox()
#        self.just_script_choice.set_text('Do not use a live instance (SQL script output)')
#        self.just_script_choice.set_tooltip('Check this if you just want an output script to execute it later')
#        self.just_script_choice.add_clicked_callback(self.just_script_toggled)
#        self.server_instance_box.add(self.just_script_choice, False)

        # Add the view that corresponds to the selected RDBMS:
        self.panel = grt.classes.ui_db_ConnectPanel()
        self.panel.initialize(grt.root.wb.rdbmsMgmt)
        view = mforms.fromgrt(self.panel.view)
        self.server_instance_box.add(view, True, True)

        box = mforms.newBox(True)
        self._store_connection_check = mforms.newCheckBox()
        self._store_connection_check.set_text("Store connection for future usage as ")
        self._store_connection_check.add_clicked_callback(self._toggle_store_connection)
        box.add(self._store_connection_check, False, False)
        self._store_connection_entry = mforms.newTextEntry()
        box.add(self._store_connection_entry, True, True)
        self._store_connection_entry.set_enabled(False)

        self.server_instance_box.add(box, False, False)
        self.content.add(self.server_instance_box, True, True)

        self.advanced_button.set_text("Test Connection")
    def _add_script_checkbox_option(self, box, name, caption, path_caption, browser_caption):
        check = mforms.newCheckBox()
        check.set_text(caption)
        box.add(check, False, True)
        vbox = mforms.newBox(False)
        vbox.set_spacing(4)
        file_box = mforms.newBox(True)
        file_box.set_spacing(4)
        file_box.add(mforms.newLabel(path_caption), False, True)
        file_entry = mforms.newTextEntry()
        file_entry.add_changed_callback(lambda self=self, option=name: setattr(self, name+"_check_duplicate", True))
        file_box.add(file_entry, True, True)
        check.add_clicked_callback(lambda box=vbox, check=check: box.set_enabled(check.get_active()))
        button = mforms.newButton()
        button.set_text("Browse...")
        button.add_clicked_callback(lambda option=name, title=browser_caption: self._browse_files(option, title))
        file_box.add(button, False, True)
        vbox.add(file_box, False, True)
        label = mforms.newLabel("You should edit this file to add the source and target server passwords before running it.")
        label.set_style(mforms.SmallHelpTextStyle)
        vbox.add(label, False, True)
        vbox.set_enabled(False)
        box.add(vbox, False, True)

        setattr(self, name+"_check_duplicate", False)
        setattr(self, name+"_checkbox", check)
        setattr(self, name+"_entry", file_entry)
Example #13
0
    def column_selected(self):
        column = self.selected_column()
        if column:
            self.column_details.set_enabled(True)
            for c in self.flag_checkboxes:
                self.column_details.remove(c)
            self.flag_checkboxes = []

            if column.simpleType:
                for flag in column.simpleType.flags:
                    check = mforms.newCheckBox()
                    check.set_text(flag)
                    check.set_active(flag in column.flags)
                    self.column_details.add(check, False, True)
                    self.flag_checkboxes.append(check)
                    check.add_clicked_callback(lambda check=check, flag=flag:
                                               self.flag_checked(check, flag))

                if column.simpleType.group.name != "string" and not column.simpleType.name.lower(
                ).endswith("text"):
                    self.charset.set_selected(0)
                    self.charset.set_enabled(False)
                else:
                    self.charset.set_enabled(True)

            if not column.collationName:
                self.charset.set_selected(0)
            else:
                self.charset.set_value(column.collationName)
        else:
            self.charset.set_selected(0)
            self.column_details.set_enabled(False)
            for c in self.flag_checkboxes:
                self.column_details.remove(c)
            self.flag_checkboxes = []
Example #14
0
    def create_ui(self):
        self.back_button.set_enabled(False)

        # Main layout structure
        self.server_instance_box = mforms.newBox(False)
        self.server_instance_box.set_spacing(8)
        instance_label = mforms.newLabel('Source RDBMS Connection Parameters')
        instance_label.set_style(mforms.BoldStyle)
        self.server_instance_box.add(instance_label, False, True)

        # Add the view that corresponds to the selected RDBMS:
        self.panel = grt.classes.ui_db_ConnectPanel()
        self.panel.initializeWithRDBMSSelector(
            grt.root.wb.rdbmsMgmt, self.supported_sources_instances)
        if not self.panel.view:
            raise Exception("NO PANEL!!!")
        view = mforms.fromgrt(self.panel.view)
        self.server_instance_box.add(view, True, True)

        box = mforms.newBox(True)
        self._store_connection_check = mforms.newCheckBox()
        self._store_connection_check.set_text(
            "Store connection for future usage as ")
        self._store_connection_check.add_clicked_callback(
            self._toggle_store_connection)
        box.add(self._store_connection_check, False, False)
        self._store_connection_entry = mforms.newTextEntry()
        box.add(self._store_connection_entry, True, True)
        self._store_connection_entry.set_enabled(False)

        self.server_instance_box.add(box, False, False)
        self.content.add(self.server_instance_box, True, True)

        self.advanced_button.set_text("Test Connection")
    def create_ui(self):
        self.back_button.set_enabled(False)

        # Main layout structure
        self.server_instance_box = mforms.newBox(False)
        self.server_instance_box.set_spacing(8)
        instance_label = mforms.newLabel('Source RDBMS Connection Parameters')
        instance_label.set_style(mforms.BoldStyle)
        self.server_instance_box.add(instance_label, False, True)

        # Add the view that corresponds to the selected RDBMS:
        self.panel = grt.classes.ui_db_ConnectPanel()
        self.panel.initializeWithRDBMSSelector(grt.root.wb.rdbmsMgmt, self.supported_sources_instances)
        if not self.panel.view:
            raise Exception("NO PANEL!!!")
        view = mforms.fromgrt(self.panel.view)
        self.server_instance_box.add(view, True, True)
        
        box = mforms.newBox(True)
        self._store_connection_check = mforms.newCheckBox()
        self._store_connection_check.set_text("Store connection for future usage as ")
        self._store_connection_check.add_clicked_callback(self._toggle_store_connection)
        box.add(self._store_connection_check, False, False)
        self._store_connection_entry = mforms.newTextEntry()
        box.add(self._store_connection_entry, True, True)
        self._store_connection_entry.set_enabled(False)

        self.server_instance_box.add(box, False, False)
        self.content.add(self.server_instance_box, True, True)

        self.advanced_button.set_text("Test Connection")
    def _add_script_checkbox_option(self, box, name, caption, path_caption,
                                    browser_caption):
        check = mforms.newCheckBox()
        check.set_text(caption)
        box.add(check, False, True)
        vbox = mforms.newBox(False)
        vbox.set_spacing(4)
        file_box = mforms.newBox(True)
        file_box.set_spacing(4)
        file_box.add(mforms.newLabel(path_caption), False, True)
        file_entry = mforms.newTextEntry()
        file_entry.add_changed_callback(lambda self=self, option=name: setattr(
            self, name + "_check_duplicate", True))
        file_box.add(file_entry, True, True)
        check.add_clicked_callback(
            lambda box=vbox, check=check: box.set_enabled(check.get_active()))
        button = mforms.newButton()
        button.set_text("Browse...")
        button.add_clicked_callback(lambda option=name, title=browser_caption:
                                    self._browse_files(option, title))
        file_box.add(button, False, True)
        vbox.add(file_box, False, True)
        label = mforms.newLabel(
            "You should edit this file to add the source and target server passwords before running it."
        )
        label.set_style(mforms.SmallHelpTextStyle)
        vbox.add(label, False, True)
        vbox.set_enabled(False)
        box.add(vbox, False, True)

        setattr(self, name + "_check_duplicate", False)
        setattr(self, name + "_checkbox", check)
        setattr(self, name + "_entry", file_entry)
Example #17
0
    def __init__(self, owner, context):
        WizardPage.__init__(self,
                            owner,
                            "Recover Backup - Select Backup",
                            wide=True)

        self.context = context
        self._backup_profiles = {}

        self.advanced_button_text = "Restore from File..."
        self.advanced_button_tooltip = """Pick a backup file created with mysqlbackup to be restored.
You may pick a single file/backup image file (.mbi) or a backup directory. 
When picking a backup directory, select the meta/backup_context.xml file inside the desired backup directory."""

        l = newLabel(
            """To recover a MySQL server from a backup, select the profile that was used to create it.
To recover from a different backup, click [Restore from File...] and select
a MySQL Enterprise Backup image file or backup directory.
Note: the server will be shutdown during restore.""")
        self.content.add(l, False, True)

        hbox = mforms.newBox(True)
        hbox.set_spacing(8)
        hbox.set_padding(20)
        hbox.add(newLabel("Backup Profile:", True), False, True)
        self._profile = mforms.newSelector()
        self._profile.set_name("profile")
        self._profile.add_changed_callback(self.profile_selected)
        hbox.add(self._profile, True, True)
        self._use_most_recent = mforms.newCheckBox()
        self._use_most_recent.set_text("Use most recent backup")
        self._use_most_recent.add_clicked_callback(self.most_recent_toggled)
        self._use_most_recent.set_active(True)
        hbox.add(self._use_most_recent, False, True)
        self.content.add(hbox, False, False)

        self._table_h = newLabel("Select Backup from List")
        self.content.add(self._table_h, False, True)
        self._table = newTreeNodeView(mforms.TreeFlatList)
        self._table.add_column(mforms.StringColumnType, "Date of Backup", 200,
                               False)
        self._table.add_column(mforms.StringColumnType, "Full/Incr.", 60,
                               False)
        self._table.add_column(mforms.IconStringColumnType, "State", 200,
                               False)
        self._table.add_column(mforms.StringColumnType, "LSN Range", 200,
                               False)
        self._table.add_column(mforms.StringColumnType, "Binlog Position", 200,
                               False)
        self._table.end_columns()

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

        self.content.add(newLabel("Details:"), False, True)

        self._text = newTextBox(mforms.VerticalScrollBar)
        self.content.add(self._text, True, True)

        self._error_icon = mforms.App.get().get_resource_path("mini_error.png")
    def create_ui(self):
        self.suspend_layout()
        self.set_spacing(16)
        
        label = mforms.newLabel("Table Data Export allows you to easily export data into CSV, JSON datafiles.\n")
        label.set_style(mforms.BoldInfoCaptionStyle)

        self.content.add(label, False, False)

        entry_box = mforms.newBox(True)
        entry_box.set_spacing(5)

        entry_box.add(mforms.newLabel("File Path:"), False, True)

        self.exportfile_path = mforms.newTextEntry()
        self.exportfile_path.add_changed_callback(lambda entry=self.exportfile_path: self.entry_changed(entry))
        entry_box.add(self.exportfile_path, True, True)
        if last_location != None:
            self.exportfile_path.set_value(last_location)
            self.confirm_file_overwrite = True
            self.get_module(True)

        browse_btn = mforms.newButton()
        browse_btn.set_text("Browse...")
        browse_btn.set_name("Browse")
        browse_btn.add_clicked_callback(self.browse)
        entry_box.add(browse_btn, False, False)
        self.content.add(entry_box, False, True)
        
        radio_box = mforms.newBox(True)
        radio_box.set_spacing(8)
        for format in self.main.formats:
            fradio = mforms.newRadioButton(1)
            fradio.set_text(format.title)
            fradio.set_active(bool(self.active_module and self.active_module.name == format.name))
            fradio.add_clicked_callback(lambda f = format: self.output_type_changed(f))
            radio_box.add(fradio, False, True)
            self.radio_opts.append({'radio':fradio, 'name': format.name})
        self.content.add(radio_box, False, True)

        self.optpanel = mforms.newPanel(mforms.TitledBoxPanel)
        self.optpanel.set_title("Options:")

        self.content.add(self.optpanel, False, True)
        self.optpanel.show(False)
        
        self.export_local_box = mforms.newBox(False)
        self.export_local_cb = mforms.newCheckBox()
        self.export_local_cb.set_text("Export to local machine")
        self.export_local_cb.set_active(True)
        self.export_local_box.add(self.export_local_cb, False, True)
        l = mforms.newLabel("""If checked, rows will be exported on the location that started Workbench.\nIf not checked, rows will be exported on the server.\nIf server and computer that started Workbench are different machines, import of that file can be done manual way only.""")
        l.set_style(mforms.SmallHelpTextStyle)
        self.export_local_box.add(l, False, True)
        
        self.content.add(self.export_local_box, False, True)
        self.resume_layout()
        
        self.load_module_options()
Example #19
0
 def create_chkbox(row):
     chk = mforms.newCheckBox()
     chk.set_active(True)
     chk.add_clicked_callback(
         lambda checkbox=chk, output=row: operator.setitem(
             output, 'active', True
             if checkbox.get_active() else False))
     return chk
    def create_ui(self):
        self.suspend_layout()
        self.set_spacing(16)
        
        label = mforms.newLabel("Table Data Export allows you to easily export data into csv, json datafiles.\n")
        label.set_style(mforms.BoldInfoCaptionStyle)

        self.content.add(label, False, False)

        entry_box = mforms.newBox(True)
        entry_box.set_spacing(5)

        entry_box.add(mforms.newLabel("File Path:"), False, True)

        self.exportfile_path = mforms.newTextEntry()
        self.exportfile_path.add_changed_callback(lambda entry=self.exportfile_path: self.entry_changed(entry))
        entry_box.add(self.exportfile_path, True, True)
        if last_location != None:
            self.exportfile_path.set_value(last_location)
            self.confirm_file_overwrite = True
            self.get_module(True)

        browse_btn = mforms.newButton()
        browse_btn.set_text("Browse...")
        browse_btn.add_clicked_callback(self.browse)
        entry_box.add(browse_btn, False, False)
        self.content.add(entry_box, False, True)
        
        radio_box = mforms.newBox(True)
        radio_box.set_spacing(8)
        for format in self.main.formats:
            fradio = mforms.newRadioButton(1)
            fradio.set_text(format.title)
            fradio.set_active(bool(self.active_module and self.active_module.name == format.name))
            fradio.add_clicked_callback(lambda f = format: self.output_type_changed(f))
            radio_box.add(fradio, False, False)
            self.radio_opts.append({'radio':fradio, 'name': format.name})
        self.content.add(radio_box, False, False)

        self.optpanel = mforms.newPanel(mforms.TitledBoxPanel)
        self.optpanel.set_title("Options:")

        self.content.add(self.optpanel, False, True)
        self.optpanel.show(False)
        
        self.export_local_box = mforms.newBox(False)
        self.export_local_cb = mforms.newCheckBox()
        self.export_local_cb.set_text("Export to local machine")
        self.export_local_cb.set_active(True)
        self.export_local_box.add(self.export_local_cb, False, True)
        l = mforms.newLabel("""If checked rows will be exported on the location that started Workbench.\nIf not checked, rows will be exported on the server.\nIf server and computer that started Workbench are different machines, import of that file can be done manual way only.""")
        l.set_style(mforms.SmallHelpTextStyle)
        self.export_local_box.add(l, False, True)
        
        self.content.add(self.export_local_box, False, True)
        self.resume_layout()
        
        self.load_module_options()
    def default_check_input(self, title):
        check = mforms.newCheckBox(False)
        text = mforms.newLabel(title)

        box = mforms.newBox(True)

        box.add(check, expand=True, fill=False)
        box.add(text, expand=True, fill=False)

        return box
Example #22
0
    def create_destination_tab(self):
        self._destination = newBox(False)
        self._destination.set_spacing(12)
        self._destination.set_padding(12)
        self._configuration.add_page(self._destination, "Options")

        table = mforms.newTable()

        table.set_row_count(7)
        table.set_column_count(2)
        table.set_row_spacing(8)
        table.set_column_spacing(4)

        add_table_field_label(table, 0, "Backup Storage Directory:")
        hbox = mforms.newBox(True)
        self._dest_directory  = newTextEntry()
        self._dest_directory.set_size(300,-1)
        hbox.add(self._dest_directory, False, False)
        self._dest_dir_button = newButton()
        self._dest_dir_button.set_text("Browse...")
        self._dest_dir_button.enable_internal_padding(False)
        self._dest_dir_button.add_clicked_callback(lambda: self.open_file_chooser(OpenDirectory, self._dest_directory))
        
        hbox.add(self._dest_dir_button, False, False)
        add_table_field_value(table, 0, hbox, mforms.HFillFlag)

        l = mforms.newLabel("Backups will be written to the specified directory in the target MySQL server.\nA new subdirectory is created for each backup, named with its timestamp.")
        l.set_style(mforms.SmallHelpTextStyle)
        add_table_field_value(table, 1, l)
        
        self._compress_backup = mforms.newCheckBox()
        self._compress_backup.set_text("Compress backup (non-incremental InnoDB backups only)")
        add_table_field_value(table, 3, self._compress_backup)
        
        self._apply_log = mforms.newCheckBox()
        self._apply_log.set_text("Apply log after backup (backup-and-apply-log)")
        add_table_field_value(table, 5, self._apply_log)
        l = mforms.newLabel("After a backup is done, an apply-log operation is needed before it can be recovered.\nThat may be done right after backup, before recovering it or at any other time.")
        l.set_style(mforms.SmallHelpTextStyle)
        add_table_field_value(table, 6, l)
        
        self._destination.add(table, False, False)
Example #23
0
    def __init__(self, owner):
        WizardPage.__init__(self, owner, "Options")
        
        self.generate_files = newCheckBox()
        self.generate_files.set_text("Generate new certificates and self-signed keys");
        self.generate_files.set_active(not self.check_all_files_availability())
        self.generate_files.set_enabled(self.check_all_files_availability())

        self.update_connection = newCheckBox()
        self.update_connection.set_text("Update the connection");
        self.update_connection.set_active(True)

        self.use_default_parameters = newCheckBox()
        self.use_default_parameters.set_text("Use default parameters");
        self.use_default_parameters.set_active(False)
        
        self.clear_button = newButton()
        self.clear_button.set_text("Clear")
        self.clear_button.add_clicked_callback(self.clear_button_clicked)
        self.clear_button.set_enabled(os.path.isdir(self.main.results_path))
Example #24
0
    def __init__(self, owner):
        WizardPage.__init__(self, owner, "Options")
        
        self.generate_files = newCheckBox()
        self.generate_files.set_text("Generate new certificates and self-signed keys");
        self.generate_files.set_active(False if self.check_all_files_availability() == True else True)
        self.generate_files.set_enabled(self.check_all_files_availability())

        self.update_connection = newCheckBox()
        self.update_connection.set_text("Update the connection");
        self.update_connection.set_active(True)

        self.use_default_parameters = newCheckBox()
        self.use_default_parameters.set_text("Use default parameters");
        self.use_default_parameters.set_active(False)
        
        self.clear_button = newButton()
        self.clear_button.set_text("Clear")
        self.clear_button.add_clicked_callback(self.clear_button_clicked)
        self.clear_button.set_enabled(os.path.isdir(self.main.results_path))
    def create_ui(self):
        self.suspend_layout()
        self.set_spacing(16)
        self.content.set_spacing(16)

        colbox = mforms.newBox(False)
        colbox.set_spacing(8)
        colbox.add(mforms.newLabel("Select columns you'd like to export"),
                   False, True)

        self.column_list = newTreeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.CheckColumnType, "Export", 50, True)
        self.column_list.add_column(mforms.StringColumnType, "Column name",
                                    self.owner.main.get_width(), False)
        self.column_list.end_columns()
        self.column_list.set_allow_sorting(True)
        self.column_list.set_size(200, -1)
        colbox.add(self.column_list, True, True)

        limit_box = mforms.newBox(True)
        limit_box.set_spacing(8)
        limit_box.add(mforms.newLabel("Count: "), False, False)
        self.limit_entry = mforms.newTextEntry()
        self.limit_entry.set_size(50, -1)
        self.limit_entry.add_changed_callback(
            lambda entry=self.limit_entry: self.entry_changed(entry))
        limit_box.add(self.limit_entry, False, False)

        offset_box = mforms.newBox(True)
        offset_box.set_spacing(8)
        offset_box.add(mforms.newLabel("Row Offset: "), False, False)
        self.offset_entry = mforms.newTextEntry()
        self.offset_entry.set_size(50, -1)
        self.offset_entry.add_changed_callback(
            lambda entry=self.offset_entry: self.entry_changed(entry))

        offset_box.add(self.offset_entry, False, False)

        sellall_cb = mforms.newCheckBox()
        sellall_cb.set_text("Select / Deselect all entries")
        sellall_cb.set_active(True)
        sellall_cb.add_clicked_callback(
            lambda cb=sellall_cb: self.sell_all(cb))

        limit_offset = mforms.newBox(True)
        limit_offset.set_spacing(8)
        limit_offset.add(sellall_cb, False, True)
        limit_offset.add_end(limit_box, False, True)
        limit_offset.add_end(offset_box, False, True)

        colbox.add(limit_offset, False, True)
        self.content.add(colbox, True, True)
        self.resume_layout()
    def create_ui(self):
        self.suspend_layout()
        self.set_spacing(16)
        self.content.set_spacing(16)
        
        colbox = mforms.newBox(False)
        colbox.set_spacing(8)
        colbox.add(mforms.newLabel("Select columns you'd like to export"), False, True)
        
        self.column_list = newTreeNodeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.CheckColumnType, "Export", 50, True)
        self.column_list.add_column(mforms.StringColumnType, "Column name", self.owner.main.get_width(), False)
        self.column_list.end_columns()
        self.column_list.set_allow_sorting(True)
        self.column_list.set_size(200, -1)
        colbox.add(self.column_list, True, True)
        
        limit_box = mforms.newBox(True)
        limit_box.set_spacing(8)
        limit_box.add(mforms.newLabel("Count: "), False, False)
        self.limit_entry = mforms.newTextEntry()
        self.limit_entry.set_size(50, -1)
        self.limit_entry.add_changed_callback(lambda entry=self.limit_entry: self.entry_changed(entry))
        limit_box.add(self.limit_entry, False, False)
        
        offset_box = mforms.newBox(True)
        offset_box.set_spacing(8)
        offset_box.add(mforms.newLabel("Row Offset: "), False, False)
        self.offset_entry = mforms.newTextEntry()
        self.offset_entry.set_size(50, -1)
        self.offset_entry.add_changed_callback(lambda entry=self.offset_entry: self.entry_changed(entry))

        offset_box.add(self.offset_entry, False, False)
        
        
        sellall_cb = mforms.newCheckBox()
        sellall_cb.set_text("Select / Deselect all entries")
        sellall_cb.set_active(True)
        sellall_cb.add_clicked_callback(lambda cb = sellall_cb: self.sell_all(cb))
        
        limit_offset = mforms.newBox(True)
        limit_offset.set_spacing(8)
        limit_offset.add(sellall_cb, False, True)
        limit_offset.add_end(limit_box, False, True)
        limit_offset.add_end(offset_box, False, True)

        colbox.add(limit_offset, False, True)
        self.content.add(colbox, True, True)
        self.resume_layout()
 def add_check_entry_row(table, row, label, name):
     check = mforms.newCheckBox()
     check.set_text(label)
     table.add(check, 0, 1, row, row+1, mforms.HFillFlag)
     entry = mforms.newTextEntry()
     entry.add_changed_callback(self.save_changes)
     table.add(entry, 1, 2, row, row+1, mforms.HFillFlag|mforms.HExpandFlag) 
     setattr(self, name+"_check", check)
     setattr(self, name+"_entry", entry)
     entry.set_enabled(False)
     def callback(entry, check):
         if not check.get_active():
             entry.set_value("-2")
         entry.set_enabled(check.get_active())
         self.save_changes()
     check.add_clicked_callback(lambda: callback(entry, check))
    def create_ui(self):
        self.content.set_padding(20)

        self.content.add(mforms.newLabel('Select the schemas to copy to the destination server and click [Start Copy >] to start the process.'), False, True)

        self.catalog_schemata = [ full_name.partition('.')[-1]
                                    for full_name in self.main.plan.migrationSource.schemaNames if full_name not in SYSTEM_SCHEMAS ]
        self.schema_selector = DatabaseSchemaSelector(self.catalog_schemata, tree_checked_callback=self.update_next_button)
        self.content.add(self.schema_selector, True, True)
  
        self.innodb_switch = mforms.newCheckBox()
        self.innodb_switch.set_text('Migrate MyISAM tables to InnoDB')
        self.innodb_switch.set_active(True)
        self.content.add_end(self.innodb_switch, False)

        self.content.add_end(mforms.newLabel(''), False)
        
        self.next_button.set_text('Start Copy >')
        self.next_button.set_enabled(False)
        def add_check_entry_row(table, row, label, name):
            check = mforms.newCheckBox()
            check.set_text(label)
            table.add(check, 0, 1, row, row + 1, mforms.HFillFlag)
            entry = mforms.newTextEntry()
            entry.add_changed_callback(self.save_changes)
            table.add(entry, 1, 2, row, row + 1,
                      mforms.HFillFlag | mforms.HExpandFlag)
            setattr(self, name + "_check", check)
            setattr(self, name + "_entry", entry)
            entry.set_enabled(False)

            def callback(entry, check):
                if not check.get_active():
                    entry.set_value("-2")
                entry.set_enabled(check.get_active())
                self.save_changes()

            check.add_clicked_callback(lambda: callback(entry, check))
    def create_ui(self):
        self.content.set_padding(20)

        self.content.add(mforms.newLabel('Select the schemas to copy to the destination server and click [Start Copy >] to start the process.'), False, True)

        match_str = r"\%s\.\%s" % (self.main.plan.migrationSource._db_module.quoteIdentifier('(.+)\\'), self.main.plan.migrationSource._db_module.quoteIdentifier('(.+)\\'))

        self.catalog_schemata = [ schema_name for catalog_name, schema_name in (re.match(match_str, full_name).groups()
                                            for full_name in [x for x in self.main.plan.migrationSource.schemaNames if x not in SYSTEM_SCHEMAS])]

        self.schema_selector = DatabaseSchemaSelector(self.catalog_schemata, tree_checked_callback=self.update_next_button)
        self.content.add(self.schema_selector, True, True)
  
        self.innodb_switch = mforms.newCheckBox()
        self.innodb_switch.set_text('Migrate MyISAM tables to InnoDB')
        self.innodb_switch.set_active(True)
        self.content.add_end(self.innodb_switch, False)

        self.content.add_end(mforms.newLabel(''), False)
        
        self.next_button.set_text('Start Copy >')
        self.next_button.set_enabled(False)
  def options_schema_box(self):
    tBox = PropelForm.spaced_box(True)

    self.widgets['export_FK_name'] = mforms.newCheckBox()
    self.widgets['export_FK_name'].set_text('export all FK name')
    self.widgets['export_FK_name'].set_active(self.db.cache['export_FK_name'])
    self.widgets['export_FK_name'].add_clicked_callback(lambda: self.refresh_text_editor_schema_box())
    tBox.add(self.widgets['export_FK_name'], False, True)

    self.widgets['export_add_ai_on_pk'] = mforms.newCheckBox()
    self.widgets['export_add_ai_on_pk'].set_text('add AI to PK')
    self.widgets['export_add_ai_on_pk'].set_active(self.db.cache['export_add_ai_on_pk'])
    self.widgets['export_add_ai_on_pk'].add_clicked_callback(lambda: self.refresh_text_editor_schema_box())
    tBox.add(self.widgets['export_add_ai_on_pk'], False, True)

    self.widgets['export_index'] = mforms.newCheckBox()
    self.widgets['export_index'].set_text('export all indexes')
    self.widgets['export_index'].set_active(self.db.cache['export_index'])
    self.widgets['export_index'].add_clicked_callback(lambda: self.refresh_text_editor_schema_box())
    tBox.add(self.widgets['export_index'], False, True)

    self.widgets['export_index_name'] = mforms.newCheckBox()
    self.widgets['export_index_name'].set_text('export all indexe\'s name')
    self.widgets['export_index_name'].set_active(self.db.cache['export_index_name'])
    self.widgets['export_index_name'].add_clicked_callback(lambda: self.refresh_text_editor_schema_box())
    tBox.add(self.widgets['export_index_name'], False, True)

    self.widgets['export_unique'] = mforms.newCheckBox()
    self.widgets['export_unique'].set_text('export all uniques')
    self.widgets['export_unique'].set_active(self.db.cache['export_unique'])
    self.widgets['export_unique'].add_clicked_callback(lambda: self.refresh_text_editor_schema_box())
    tBox.add(self.widgets['export_unique'], False, True)

    self.widgets['export_unique_name'] = mforms.newCheckBox()
    self.widgets['export_unique_name'].set_text('export all unique\'s name')
    self.widgets['export_unique_name'].set_active(self.db.cache['export_unique_name'])
    self.widgets['export_unique_name'].add_clicked_callback(lambda: self.refresh_text_editor_schema_box())
    tBox.add(self.widgets['export_unique_name'], False, True)

    self.add(tBox, False, True)
Example #32
0
    def __init__(self, main):
        WizardPage.__init__(self, main, "Create Target Results", wide=True)

        self.main.add_wizard_page(self, "ObjectMigration",
                                  "Create Target Results")

        text = """Scripts to create the target schema were executed. No data has been migrated yet. Review the creation report below 
for errors or warnings. If there are any errors, you can manually fix the scripts and click [Recreate Objects] to retry 
the schema creation or return to the Manual Editing page to correct them there and retry the target creation."""
        description = mforms.newLabel(text)
        description.set_name("Page Description")
        self.content.add(description, False, True)

        hbox = mforms.newBox(True)
        hbox.set_spacing(12)
        hbox.set_homogeneous(True)
        self._tree = mforms.newTreeView(mforms.TreeFlatList)
        self._tree.set_name("Script Results")
        self._tree.add_column(mforms.IconStringColumnType, "Object", 200,
                              False)
        self._tree.add_column(mforms.IconStringColumnType, "Result", 600,
                              False)
        self._tree.end_columns()
        self._tree.add_changed_callback(self._selection_changed)
        hbox.add(self._tree, True, True)
        #self.content.add(self._tree, True, True)

        self._advbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._advbox.set_title("SQL CREATE Script for Selected Object")
        self._advbox.set_name("SQL IDE")
        box = mforms.newBox(False)
        self._code = mforms.newCodeEditor()
        self._code.set_language(mforms.LanguageMySQL)
        self._code.add_changed_callback(self._code_changed)
        box.add(self._code, True, True)
        vbox = mforms.newBox(True)
        vbox.set_padding(12)
        vbox.set_spacing(8)
        self._comment_check = mforms.newCheckBox()
        self._comment_check.set_text("Comment out")
        self._comment_check.set_name("Comment Out")
        self._comment_check.add_clicked_callback(self._comment_clicked)
        vbox.add(self._comment_check, False, True)

        self._revert_btn = mforms.newButton()
        self._revert_btn.set_text("Discard")
        vbox.add_end(self._revert_btn, False, True)
        self._revert_btn.add_clicked_callback(self._discard_clicked)

        self._apply_btn = mforms.newButton()
        self._apply_btn.set_text("Apply")
        vbox.add_end(self._apply_btn, False, True)
        self._apply_btn.add_clicked_callback(self._apply_clicked)
        box.add(vbox, False, True)

        self._advbox.add(box)
        #self._advbox.set_size(-1, 200)
        #self._advbox_shown = True
        #self.go_advanced() # toggle to hide

        self.advanced_button.set_text("Recreate Objects")

        #self.content.add(self._advbox, False, True)
        hbox.add(self._advbox, True, True)
        self.content.add(hbox, True, True)

        self._msgbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._msgbox.set_title("Output Messages")
        self._msgbox.set_name("Output Messages")
        box = mforms.newBox(False)
        box.set_padding(8)
        self._msgs = mforms.newTextBox(mforms.VerticalScrollBar)
        box.add(self._msgs, True, True)
        self._msgbox.add(box)
        self.content.add(self._msgbox, False, True)
        self._msgbox.set_size(-1, 200)

        self._error_tables = []
    def create_ui(self):
        self.set_spacing(16)        
        layer_box = mforms.newBox(True)
        layer_box.set_spacing(8)
        layer_heading = mforms.newLabel("Layer name:")
        layer_box.add(layer_heading, False, False)
        self.layer_name_lbl = mforms.newLabel("")
        layer_box.add(self.layer_name_lbl, False, False)
        self.content.add(layer_box, False, False)

        epsg_box = mforms.newBox(True)
        epsg_box.set_spacing(8)
        epsg_box_heading = mforms.newLabel("EPSG:")
        epsg_box.add(epsg_box_heading, False, False)
        self.epsg_lbl = mforms.newLabel("")
        epsg_box.add(self.epsg_lbl, False, False)
        self.content.add(epsg_box, False, False)
        
        entry_box = mforms.newBox(True)
        entry_box.set_spacing(12)

        entry_box.add(mforms.newLabel("Destination table:"), False, True)

        self.table_name = mforms.newTextEntry()
        entry_box.add(self.table_name, True, True)
        
        self.content.add(entry_box, False, True)
        entry_box.show(True)

        cbox = mforms.newBox(False)

        self.column_list = newTreeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.CheckColumnType, "", 40, True)
        self.column_list.add_column(mforms.StringColumnType, "Column name", 300, False)
        self.column_list.end_columns()
        self.column_list.set_size(-1, 150)

        cbox.add(small_label("Please select the columns you want to import:"), False, True)
        cbox.add(self.column_list, False, True)

        self.content.add(cbox, False, True)
        cbox.show(True)
        
        options_layer = mforms.newPanel(mforms.TitledBoxPanel)
        options_layer.set_title("Additional options")
        
        options_box = mforms.newBox(False)
        options_box.set_spacing(12)
        options_box.set_padding(12)
        
        boxfailures = mforms.newBox(False)
        
        self.skipfailures_chb = newCheckBox()
        self.skipfailures_chb.set_text("Skip failures");
        self.skipfailures_chb.set_active(False)
        
        boxfailures.add(self.skipfailures_chb, False, False)
        boxfailures.add(small_label("If an error occurs ignore it and continue processing data."), False, False)
        options_box.add(boxfailures, False, False)
        
        boxappend = mforms.newBox(False)
        
        self.append_chb = newCheckBox()
        self.append_chb.set_text("Append to existing data");
        self.append_chb.set_active(False)
        boxappend.add(self.append_chb, False, False)
        boxappend.add(small_label("Append to existing table instead of creating a new one."), False, False)
        options_box.add(boxappend, False, False)
        
        boxoverwrite = mforms.newBox(False)
        
        self.overwrite_chb = newCheckBox()
        self.overwrite_chb.set_text("Overwrite existing data");
        self.overwrite_chb.set_active(False)
        
        self.append_chb.add_clicked_callback(lambda checkbox1 = self.append_chb, checkbox2 = self.overwrite_chb: self.one_check_only(checkbox1, checkbox2))
        self.overwrite_chb.add_clicked_callback(lambda checkbox2 = self.append_chb, checkbox1 = self.overwrite_chb: self.one_check_only(checkbox1, checkbox2))
        boxoverwrite.add(self.overwrite_chb, False, False)
        boxoverwrite.add(small_label("Drop the selected table and recreate it."), False, False)
        options_box.add(boxoverwrite, False, False)
        
        if self.support_spatial_index:
            boxspatial = mforms.newBox(False)
            self.spatial_index_chb = newCheckBox()
            self.spatial_index_chb.set_text("Create spatial index")
            self.spatial_index_chb.set_active(False)
            boxspatial.add(self.spatial_index_chb, False, False)
            boxspatial.add(small_label("import will make spatial index around geometry column"), False, False)
            options_box.add(boxspatial, False, False)
        
        options_layer.add(options_box)
        options_layer.show(True)
        
        self.content.add(options_layer, False, False)

        boxconvert = mforms.newBox(False)
        entry_box = mforms.newBox(True)
        entry_box.set_spacing(8)
        entry_box.add(mforms.newLabel("Convert data to the following EPSG:"), False, True)
        self.convert_to_epsg = mforms.newTextEntry()
        entry_box.add(self.convert_to_epsg, False, False)
        boxconvert.add(entry_box, True, True)
        boxconvert.add(small_label("leave empty to import the data with no conversion"), False, False)
        
        self.content.add(boxconvert, False, True)
        self.get_info()
Example #34
0
    def __init__(self, conn):
        mforms.Form.__init__(self, None)
        self._conn = conn
        self.versionstr = conn.parameterValues.get("serverVersion", None)

        try:
            self.version = Version.fromstr(self.versionstr)
        except:
            self.version = None

        self.set_title("Password Expired")

        vbox = mforms.newBox(False)
        vbox.set_padding(20)
        vbox.set_spacing(18)

        user = conn.parameterValues["userName"]
        l = newLabel(
            "Password for MySQL account '%s'@%s expired.\nPlease pick a new password:"******"Mysql@", "")))
        l.set_style(mforms.BoldStyle)
        vbox.add(l, False, True)

        box = mforms.newTable()
        box.set_padding(1)
        box.set_row_count(3)
        box.set_column_count(2)
        box.set_column_spacing(7)
        box.set_row_spacing(8)

        hbox = mforms.newBox(True)
        hbox.set_spacing(12)
        icon = mforms.newImageBox()
        icon.set_image(mforms.App.get().get_resource_path("wb_lock.png"))
        hbox.add(icon, False, True)
        hbox.add(box, True, True)
        vbox.add(hbox, False, True)

        self.old_password = mforms.newTextEntry(mforms.PasswordEntry)
        self.old_password.set_name("Old Password")
        box.add(newLabel("Old Password:"******"New Password")
        box.add(newLabel("New Password:"******"Confirm Password")
        box.add(newLabel("Confirm:", True), 0, 1, 2, 3,
                mforms.HFillFlag | mforms.VFillFlag)
        box.add(self.confirm, 1, 2, 2, 3,
                mforms.HFillFlag | mforms.HExpandFlag)

        self.legacy = mforms.newCheckBox()
        self.legacy.set_text("This server version is < 5.7")
        if self.version:
            self.legacy.set_active(
                not self.version.is_supported_mysql_version_at_least(5, 7))
            self.legacy.show(False)
        else:
            self.legacy.show(True)
        vbox.add(self.legacy, mforms.HFillFlag | mforms.VFillFlag)

        bbox = newBox(True)
        bbox.set_spacing(8)
        self.ok = newButton()
        self.ok.set_text("OK")

        self.cancel = newButton()
        self.cancel.set_text("Cancel")
        mforms.Utilities.add_end_ok_cancel_buttons(bbox, self.ok, self.cancel)

        vbox.add_end(bbox, False, True)

        self.set_content(vbox)

        self.set_size(500, 300)
        self.center()
    def __init__(self, main):
        WizardPage.__init__(self, main, "Create Target Results", wide=True)

        self.main.add_wizard_page(self, "ObjectMigration", "Create Target Results")

        text = """Scripts to create the target schema were executed. No data has been migrated yet. Review the creation report below 
for errors or warnings. If there are any errors, you can manually fix the scripts and click [Recreate Objects] to retry 
the schema creation or return to the Manual Editing page to correct them there and retry the target creation."""
        self.content.add(mforms.newLabel(text), False, True)

        hbox = mforms.newBox(True)
        hbox.set_spacing(12)
        hbox.set_homogeneous(True)
        self._tree = mforms.newTreeNodeView(mforms.TreeFlatList)
        self._tree.add_column(mforms.IconStringColumnType, "Object", 200, False)
        self._tree.add_column(mforms.IconStringColumnType, "Result", 600, False)
        self._tree.end_columns()
        self._tree.add_changed_callback(self._selection_changed)
        hbox.add(self._tree, True, True)
        #self.content.add(self._tree, True, True)

        self._advbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._advbox.set_title("SQL CREATE Script for Selected Object")
        box = mforms.newBox(False)
        self._code = mforms.newCodeEditor()
        self._code.set_language(mforms.LanguageMySQL)
        self._code.add_changed_callback(self._code_changed)
        box.add(self._code, True, True)
        vbox = mforms.newBox(True)
        vbox.set_padding(12)
        vbox.set_spacing(8)
        self._comment_check = mforms.newCheckBox()
        self._comment_check.set_text("Comment out")
        self._comment_check.add_clicked_callback(self._comment_clicked)
        vbox.add(self._comment_check, False, True)

        self._revert_btn = mforms.newButton()
        self._revert_btn.set_text("Discard")
        vbox.add_end(self._revert_btn, False, True)
        self._revert_btn.add_clicked_callback(self._discard_clicked)

        self._apply_btn = mforms.newButton()
        self._apply_btn.set_text("Apply")
        vbox.add_end(self._apply_btn, False, True)
        self._apply_btn.add_clicked_callback(self._apply_clicked)
        box.add(vbox, False, True)

        self._advbox.add(box)
        #self._advbox.set_size(-1, 200)
        #self._advbox_shown = True
        #self.go_advanced() # toggle to hide
        
        self.advanced_button.set_text("Recreate Objects")
        
        #self.content.add(self._advbox, False, True)
        hbox.add(self._advbox, True, True)
        self.content.add(hbox, True, True)

        self._msgbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._msgbox.set_title("Output Messages")
        box = mforms.newBox(False)
        box.set_padding(8)
        self._msgs = mforms.newTextBox(mforms.VerticalScrollBar)
        box.add(self._msgs, True, True)
        self._msgbox.add(box)
        self.content.add(self._msgbox, False, True)
        self._msgbox.set_size(-1, 200)

        self._error_tables = []
    def __init__(self, types_to_display, database_objects, ui_settings={}):
        super(DatabaseObjectSelector, self).__init__(False)
        self.database_objects = database_objects
        self.supported_object_types = types_to_display
        
        self.ui_settings = {
            'tables' : { 'icon': 'db.Table.many.32x32.png',
                        'small_icon': 'db.Table.16x16.png',
                        'group_label': 'Migrate Table objects',
                        'group_selected': True,
                        'status_text': '%(total)d total, %(selected)d selected',
                        'show_details': False,
                      },
            'views'  : { 'icon': 'db.View.many.32x32.png',
                        'small_icon': 'db.View.16x16.png',
                        'group_label': 'Migrate View objects',
                        'group_selected': True,
                        'status_text': '%(total)d total, %(selected)d selected',
                        'show_details': False,
                      },
            'routines':{ 'icon': 'db.Routine.many.32x32.png',
                        'small_icon': 'db.Routine.16x16.png',
                        'group_label': 'Migrate Routine objects',
                        'group_selected': True,
                        'status_text': '%(total)d total, %(selected)d selected',
                        'show_details': False,
                      },
            'routineGroups':{ 'icon': 'db.RoutineGroup.48x48.png',
                        'small_icon': 'db.RoutineGroup.16x16.png',
                        'group_label': 'Migrate Routine Group/Package objects',
                        'group_selected': True,
                        'status_text': '%(total)d total, %(selected)d selected',
                        'show_details': False,
                      },
            'synonyms':{ 'icon': 'grt_object.png',
                        'small_icon': 'grt_object.png',
                        'group_label': 'Migrate Synonym objects',
                        'group_selected': True,
                        'status_text': '%(total)d total, %(selected)d selected',
                        'show_details': False,
                      },
            'structuredTypes':{ 'icon': 'grt_object.png',
                        'small_icon': 'grt_object.png',
                        'group_label': 'Migrate Structured Type objects',
                        'group_selected': True,
                        'status_text': '%(total)d total, %(selected)d selected',
                        'show_details': False,
                      },
            'sequences':{ 'icon': 'grt_object.png',
                        'small_icon': 'grt_object.png',
                        'group_label': 'Migrate Sequence objects',
                        'group_selected': True,
                        'status_text': '%(total)d total, %(selected)d selected',
                        'show_details': False,
                      },
        }
        
        # Update the ui settings dict with the custom settings supplied by the user (if any):
        if isinstance(ui_settings, dict):
            for key, value in ui_settings.iteritems():
                if key not in self.ui_settings or not isinstance(value, dict):
                    continue
                self.ui_settings[key].update(value)
        
        # Create UI:
        self.set_padding(8)
        self.set_spacing(8)
        
        self.ui = {}
        for group in self.supported_object_types:
            if group not in self.database_objects or group not in self.ui_settings:
                continue
            self.ui[group] = {}
            group_objects = self.database_objects[group]
            
            group_panel = mforms.newPanel(mforms.BorderedPanel)
            group_box = mforms.newBox(False)
            group_box.set_padding(8)
            group_box.set_spacing(8)
            
            header_box = mforms.Box(True)
            header_box.set_spacing(8)

            icon = mforms.newImageBox()
            icon.set_image(self.ui_settings[group]['icon'])
            header_box.add(icon, False)
            
            text_box = mforms.Box(False)
            group_selector = mforms.newCheckBox()
            group_selector.set_text(self.ui_settings[group]['group_label'])
            group_selector.set_active(bool(self.ui_settings[group]['group_selected']))
            group_selector.add_clicked_callback(functools.partial(self.group_checkbox_clicked, group=group))
            text_box.add(group_selector, False)
            info_label = mforms.newLabel(self.ui_settings[group]['status_text'] % {'total': len(group_objects), 
                                       'selected': len(group_objects) if self.ui_settings[group]['group_selected'] else 0 })
            info_label.set_style(mforms.SmallHelpTextStyle)
            text_box.add(info_label, False)
            header_box.add(text_box, False)
            
            show_details = self.ui_settings[group]['show_details']
            self.ui_settings[group]['_showing_details'] = show_details
            filter_button = mforms.newButton()
            filter_button.set_text('Hide Selection' if show_details else 'Show Selection')
            filter_button.set_enabled(bool(self.ui_settings[group]['group_selected']))
            filter_button.add_clicked_callback(functools.partial(self.filter_button_clicked, group=group))
            header_box.add_end(filter_button, False, True)
            
            group_box.add(header_box, False)
            
            # The invisible stuff:
            if len(group_objects) > 0:
                box = mforms.newBox(True)
                search_entry = mforms.newTextEntry(mforms.SearchEntry)
                search_entry.set_placeholder_text("Filter objects (wildcards chars * and ? are allowed)")
                search_entry.add_changed_callback(functools.partial(self.search_entry_changed, group=group))
                box.add(search_entry, False, True)
                group_box.add(box, False, True)
                search_entry.set_size(350, -1)

                filter_container = mforms.newBox(True)
                filter_container.set_spacing(8)

                available_list = mforms.newTreeNodeView(mforms.TreeFlatList)
                available_list.add_column(mforms.IconColumnType, 'Available Objects', 300, False)
                available_list.end_columns()
                available_list.set_selection_mode(mforms.TreeSelectMultiple)
                available_list.set_allow_sorting(False)
                filter_container.add(available_list, True, True)

                control_box = mforms.newBox(False)
                control_box.set_padding(0, 30, 0, 30)
                control_box.set_spacing(4)
                add_button = mforms.newButton()
                add_button.set_text('>')
                add_button.enable_internal_padding(False)
                add_button.add_clicked_callback(functools.partial(self.move_button_clicked, group=group, operation='add'))
                control_box.add(add_button, False)
                remove_button = mforms.newButton()
                remove_button.set_text('<')
                remove_button.enable_internal_padding(False)
                remove_button.add_clicked_callback(functools.partial(self.move_button_clicked, group=group, operation='remove'))
                control_box.add(remove_button, False)
                add_all_button = mforms.newButton()
                add_all_button.set_text('>>')
                add_all_button.enable_internal_padding(False)
                add_all_button.add_clicked_callback(functools.partial(self.move_button_clicked, group=group, operation='add_all'))
                control_box.add(add_all_button, False)
                remove_all_button = mforms.newButton()
                remove_all_button.set_text('<<')
                remove_all_button.enable_internal_padding(False)
                remove_all_button.add_clicked_callback(functools.partial(self.move_button_clicked, group=group, operation='remove_all'))
                control_box.add(remove_all_button, False)
                filter_container.add(control_box, False, False)


                selected_list = mforms.newTreeNodeView(mforms.TreeFlatList)
                selected_list.add_column(mforms.IconColumnType, 'Objects to Migrate', 300, False)
                selected_list.end_columns()
                selected_list.set_selection_mode(mforms.TreeSelectMultiple)
                selected_list.set_allow_sorting(False)
                for item in sorted(group_objects):
                    node = selected_list.add_node()
                    node.set_icon_path(0, self.ui_settings[group]['small_icon'])
                    node.set_string(0, item)
                filter_container.add(selected_list, True, True)
                
                group_box.add(filter_container, True, True)
                
                filter_container.show(bool(show_details))
            
                self.ui[group].update( {
                    'filter_container': filter_container,
                    'available_list': available_list,
                    'selected_list': selected_list,
                    'search_entry': search_entry,
                    } )
            else:  # Empty object list
                filter_button.set_enabled(False)

            self.ui[group].update ( {
                'icon': icon,
                'group_selector': group_selector,
                'group_panel': group_panel,
                'info_label': info_label,
                'filter_button': filter_button,
                'all_objects': set(group_objects),
                'has_elements': bool(len(group_objects)),
                'available': set(),
                'selected': set(group_objects),
                'objects_passing_filter': set(group_objects),
                }  )
            group_panel.add(group_box)
            self.add(group_panel, False, True)
Example #37
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)
    def create_ui(self):
        self.content.set_spacing(4)
        self.content.add(mforms.newLabel("Review and edit migrated objects. You can manually edit the generated SQL before applying them to the target database."), False, True)
        
        hbox = mforms.newBox(True)
        self.tree_head_label = mforms.newLabel("Migrated Objects")
        hbox.add(self.tree_head_label, False, False)
        self._filter = mforms.newSelector()
        self._filter.add_items(["Migration Problems", "All Objects", "Column Mappings"])
        self._filter.add_changed_callback(self._filter_changed)
        hbox.add_end(self._filter, False, True)
        hbox.add_end(mforms.newLabel("View:"), False, False)
        self.content.add(hbox, False, True)
        
        self._no_errors_text = "No migration problems found. %d warning(s).\nUse the View pulldown menu to review all objects."
        self._no_errors = mforms.newLabel('')  # Label text will be set later when the warning count is calculated
        self._no_errors.set_style(mforms.BigStyle)
        self._no_errors.set_text_align(mforms.MiddleLeft)
        self.content.add(self._no_errors, True, True)
        
        self._tree = mforms.newTreeView(mforms.TreeDefault)
        self._tree.add_column(mforms.IconStringColumnType, "Source Object", 200, False)
        self._tree.add_column(mforms.IconStringColumnType, "Target Object", 200, True)
        self._tree.add_column(mforms.IconStringColumnType, "Migration Message", 300, False)
        self._tree.end_columns()
        self._tree.add_changed_callback(self._selection_changed)
        self.content.add(self._tree, True, True)
        self._tree.set_cell_edited_callback(self._cell_edited)

        self._all_menu = mforms.newContextMenu()
        self._all_menu.add_will_show_callback(self.all_menu_will_show)
        self._all_menu.add_check_item_with_title("Skip Object", self.skip_object, "skip_object")

        self._tree.set_context_menu(self._all_menu)

        
        self._columns = mforms.newTreeView(mforms.TreeShowColumnLines|mforms.TreeShowRowLines|mforms.TreeFlatList)
        self.COL_SOURCE_SCHEMA = self._columns.add_column(mforms.StringColumnType, "Source Schema", 100, False)
        self.COL_SOURCE_TABLE = self._columns.add_column(mforms.IconStringColumnType, "Source Table", 100, False)
        self.COL_SOURCE_COLUMN = self._columns.add_column(mforms.IconStringColumnType, "Source Column", 100, False)
        self.COL_SOURCE_TYPE = self._columns.add_column(mforms.StringColumnType, "Source Type", 100, False)
        self.COL_SOURCE_FLAGS = self._columns.add_column(mforms.StringColumnType, "Source Flags", 100, False)
        self.COL_SOURCE_NOTNULL = self._columns.add_column(mforms.CheckColumnType, "NN", 25, False)
        self.COL_SOURCE_DEFAULT = self._columns.add_column(mforms.StringColumnType, "Source Default Value", 100, False)
        self.COL_SOURCE_COLLATION = self._columns.add_column(mforms.StringColumnType, "Source Collation", 100, False)
        self.COL_TARGET_SCHEMA = self._columns.add_column(mforms.StringColumnType, "Target Schema", 100, False)
        self.COL_TARGET_TABLE = self._columns.add_column(mforms.IconStringColumnType, "Target Table", 100, False)
        self.COL_TARGET_COLUMN = self._columns.add_column(mforms.IconStringColumnType, "Target Column", 100, True)
        self.COL_TARGET_TYPE = self._columns.add_column(mforms.StringColumnType, "Target Type", 100, True)
        self.COL_TARGET_FLAGS = self._columns.add_column(mforms.StringColumnType, "Target Flags", 100, True)
        self.COL_TARGET_AI = self._columns.add_column(mforms.CheckColumnType, "AI", 25, True)
        self.COL_TARGET_NOTNULL = self._columns.add_column(mforms.CheckColumnType, "NN", 25, True)
        self.COL_TARGET_DEFAULT = self._columns.add_column(mforms.StringColumnType, "Target Default Value", 100, True)
        self.COL_TARGET_COLLATION = self._columns.add_column(mforms.StringColumnType, "Target Collation", 100, True)
        self.COL_MESSAGE = self._columns.add_column(mforms.IconStringColumnType, "Migration Message", 300, False)
        self._columns.end_columns()
        self._columns.set_allow_sorting(True)
        self._columns.set_selection_mode(mforms.TreeSelectMultiple)
        self._columns.add_changed_callback(self._selection_changed)
        self.content.add(self._columns, True, True)
        self._columns.set_cell_edited_callback(self._columns_cell_edited)
        self._columns.show(False)
        
        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self._menu.add_item_with_title("Set Target Type of Selected Columns...", self.set_target_type, "set_target_type")
        self._menu.add_item_with_title("Find and Replace Target Type...", self.replace_target_type, "replace_target_type")
        self._menu.add_item_with_title("Find and Replace Target Flags...", self.replace_target_flags, "replace_target_flags")
        self._menu.add_item_with_title("Find and Replace Target Default Value...", self.replace_target_default_value, "replace_target_default_value")
        self._menu.add_item_with_title("Find and Replace Target Collation...", self.replace_target_collation, "replace_target_collation")
        self._columns.set_context_menu(self._menu)
        
        self.help_label = mforms.newLabel("You can rename target schemas and tables, and change column definitions by clicking them once selected.")
        self.help_label.set_style(mforms.SmallStyle)
        self.content.add(self.help_label, False, True)
        
        self._advbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._advbox.set_title("SQL CREATE Script for Selected Object")
        box = mforms.newBox(True)
        self._code = mforms.newCodeEditor()
        self._code.set_language(mforms.LanguageMySQL)
        self._code.add_changed_callback(self._code_changed)
        box.add(self._code, True, True)
        vbox = mforms.newBox(False)
        vbox.set_padding(12)
        vbox.set_spacing(8)

        self._lock_check = mforms.newCheckBox()
        self._lock_check.set_text("Lock edited SQL")
        self._lock_check.set_tooltip("Lock the SQL code to the edited one, preventing automatic regenerations from discarding changes made directly to the SQL script.")
        self._lock_check.add_clicked_callback(self._lock_clicked)
        vbox.add(self._lock_check, False, True)

        self._comment_check = mforms.newCheckBox()
        self._comment_check.set_text("Comment out")
        self._comment_check.set_tooltip("Mark the object to be commented out on the generated script, making it not get created in the target server.")
        self._comment_check.add_clicked_callback(self._comment_clicked)
        vbox.add(self._comment_check, False, True)
        
        self._sql_outdated_label = mforms.newLabel("Code is outdated")
        self._sql_outdated_label.show(False)
        self._sql_outdated_label.set_tooltip("The locked SQL code seems to be outdated compared to a newer, automatically generated one. Unlocking the object will update it, but your changes will be lost.")
        vbox.add(self._sql_outdated_label, False, True)

        self._revert_btn = mforms.newButton()
        self._revert_btn.set_text("Discard Changes")
        vbox.add_end(self._revert_btn, False, True)
        self._revert_btn.add_clicked_callback(self._discard_clicked)

        self._apply_btn = mforms.newButton()
        self._apply_btn.set_text("Apply Changes")
        vbox.add_end(self._apply_btn, False, True)
        self._apply_btn.add_clicked_callback(self._apply_clicked)
        box.add(vbox, False, True)

        self._advbox.add(box)
        self._advbox.set_size(-1, 200)
        self._advbox_shown = True
        self.go_advanced() # toggle to hide
                
        self.content.add(self._advbox, False, True)
        
        self._filter_errors = False
        self._filter_changed()
    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)
Example #40
0
    def create_ui(self):
        self.suspend_layout()

        if not self.server_profile.admin_enabled:
            self.add(no_remote_admin_warning_label(self.server_profile), False,
                     True)
            self.resume_layout()
            return

        self.main_view.ui_profile.apply_style(self, 'page')
        self.set_padding(8)  # TODO check padding

        # Top layout structure.
        content = newBox(False)
        self.add(content, True, True)

        # A spacer at the bottom of the page.
        spacer = newBox(True)
        spacer.set_size(-1, 40)
        self.add(spacer, False, True)

        # Left pane (start/stop).
        heading = newLabel("Database Server Status")
        heading.set_style(mforms.BoldStyle)
        content.add(heading, False, True)

        left_pane = newBox(False)
        left_pane.set_spacing(8)

        self.long_status_msg = newLabel("The database server is stopped")
        self.long_status_msg.set_style(mforms.SmallStyle)

        status_message_part = newLabel("The database server instance is ")
        self.short_status_msg = newLabel("...")
        self.short_status_msg.set_color("#DD0000")

        self.start_stop_btn = newButton()
        self.start_stop_btn.set_text("Start server")
        self.start_stop_btn.add_clicked_callback(self.start_stop_clicked)

        start_stop_hbox = newBox(True)
        start_stop_hbox.add(status_message_part, False, True)
        start_stop_hbox.add(self.short_status_msg, False, True)
        start_stop_hbox.add(newLabel("  "), False, False)
        start_stop_hbox.add(self.start_stop_btn, False, False)

        left_pane.add(self.long_status_msg, False, True)
        left_pane.add(start_stop_hbox, False, False)

        description = newLabel(
            "If you stop the server, you and your applications will not be able to use the Database and all current connections will be closed\n"
        )
        description.set_style(mforms.SmallStyle)
        left_pane.add(description, False, False)

        auto_start_checkbox = newCheckBox()
        auto_start_checkbox.set_text(
            "Automatically Start Database Server on Startup")
        auto_start_checkbox.set_active(True)

        description = newLabel(
            "You may select to have the Database server start automatically whenever the computer starts up."
        )
        description.set_style(mforms.SmallStyle)
        description.set_wrap_text(True)

        content.add(left_pane, False, True)

        # Right pane (log).
        heading = newLabel("Startup Message Log")
        heading.set_style(mforms.BoldStyle)
        content.add(heading, False, True)

        right_pane = newBox(False)
        right_pane.set_spacing(8)

        self.startup_msgs_log = newTextBox(mforms.BothScrollBars)
        self.startup_msgs_log.set_read_only(True)
        right_pane.add(self.startup_msgs_log, True, True)

        button_box = newBox(True)
        self.refresh_button = newButton()
        self.refresh_button.set_text("Refresh Status")
        self.refresh_button.add_clicked_callback(lambda: self.refresh(2))
        button_box.add(self.refresh_button, False, False)

        self.copy_to_clipboard_button = newButton()
        self.copy_to_clipboard_button.set_size(150, -1)
        self.copy_to_clipboard_button.set_text("Copy to Clipboard")
        self.copy_to_clipboard_button.add_clicked_callback(
            self.copy_to_clipboard)
        button_box.add_end(self.copy_to_clipboard_button, False, False)

        self.clear_messages_button = newButton()
        self.clear_messages_button.set_size(150, -1)
        self.clear_messages_button.set_text("Clear Messages")
        self.clear_messages_button.add_clicked_callback(self.clear_messages)
        button_box.add_end(self.clear_messages_button, False, False)
        right_pane.add(button_box, False, True)

        content.add(right_pane, True, True)

        self.resume_layout()

        self.ctrl_be.add_me_for_event("server_started", self)
        self.ctrl_be.add_me_for_event("server_stopped", self)
Example #41
0
    def create_schedule_tab(self):
        self._schedule = newBox(False)
        self._schedule.set_spacing(12)
        self._schedule.set_padding(12)
        self._configuration.add_page(self._schedule, "Schedule")

        
        self._full_backup_schedule = mforms.newCheckBox()
        self._full_backup_schedule.set_text("Perform full backups every")
        self._schedule.add(self._full_backup_schedule, False, False)
        self._full_backup_schedule.add_clicked_callback(self.full_backup_schedule_clicked)

        self._full_backup_box = mforms.newBox(True)

        # Selector for frequency
        self._full_backup_frequency  = newSelector()
        self._full_backup_frequency.set_size(100, -1)
        for freq in self._freqs:
            self._full_backup_frequency.add_item(freq)
        self._full_backup_frequency.add_changed_callback(self.schedule_full_freq_changed)
        self._full_backup_box.add(self._full_backup_frequency, False, False)
        
        self._full_label1 = newLabel(" on ")
        self._full_backup_box.add(self._full_label1, False, False)
        
        # Selector for days of the week
        dayhbox = newBox(True)
        self._full_backup_dow  = newSelector()
        self._full_backup_dow.set_size(100, -1)
        for day in self._days:
            self._full_backup_dow.add_item(day)
        dayhbox.add(self._full_backup_dow, False, False)
        
        # Selector for days in the month
        self._full_backup_dom  = newSelector()
        self._full_backup_dom.set_size(50, -1)
        for day in self._monthdays:
            self._full_backup_dom.add_item(day)
        dayhbox.add(self._full_backup_dom, False, False)
        self._full_backup_box.add(dayhbox, False, False)
        
        self._full_label2 = newLabel(" at ")
        self._full_backup_box.add(self._full_label2, False, False)

        # Selector for the hour
        self._full_backup_hour  = newSelector()
        self._full_backup_hour.set_size(50, -1)
        for index in range(24):
            self._full_backup_hour.add_item(str(index).zfill(2))
        self._full_backup_box.add(self._full_backup_hour, False, False)
        
        self._full_label3 = newLabel(" : ")
        self._full_backup_box.add(self._full_label3, False, False)
        
        self.schedule_full_freq_changed()
        self._full_backup_box.set_enabled(False)

        # Selector for the minute
        self._full_backup_minute  = newSelector()
        self._full_backup_minute.set_size(50, -1)
        for index in range(60):
            self._full_backup_minute.add_item(str(index).zfill(2))
        self._full_backup_box.add(self._full_backup_minute, False, False)
        self._schedule.add(self._full_backup_box, False, False)
        
        self._inc_backup_schedule = mforms.newCheckBox()
        self._inc_backup_schedule.set_text("Perform incremental backups every")
        self._schedule.add(self._inc_backup_schedule, False, False)
        self._inc_backup_schedule.add_clicked_callback(self.inc_backup_schedule_clicked)
        
        self._inc_backup_box = mforms.newBox(True)

        # Selector for frequency
        self._inc_backup_frequency  = newSelector()
        self._inc_backup_frequency.set_size(100, -1)
        for freq in self._freqs:
            self._inc_backup_frequency.add_item(freq)
        self._inc_backup_frequency.add_changed_callback(self.schedule_inc_freq_changed)
        self._inc_backup_box.add(self._inc_backup_frequency, False, False)
        
        self._inc_label1 = newLabel(" on ")
        self._inc_backup_box.add(self._inc_label1, False, False)
        
        # Selector for days of the week
        dayhbox = newBox(True)
        self._inc_backup_dow  = newSelector()
        self._inc_backup_dow.set_size(100, -1)
        for day in self._days:
            self._inc_backup_dow.add_item(day)
        dayhbox.add(self._inc_backup_dow, False, False)
        
        # Selector for days in the month
        self._inc_backup_dom  = newSelector()
        self._inc_backup_dom.set_size(50, -1)
        for day in self._monthdays:
            self._inc_backup_dom.add_item(day)
        dayhbox.add(self._inc_backup_dom, False, False)
        self._inc_backup_box.add(dayhbox, False, False)
        
        self._inc_label2 = newLabel(" at ")
        self._inc_backup_box.add(self._inc_label2, False, False)

        # Selector for the hour
        self._inc_backup_hour  = newSelector()
        self._inc_backup_hour.set_size(50, -1)
        for index in range(24):
            self._inc_backup_hour.add_item(str(index).zfill(2))
        self._inc_backup_box.add(self._inc_backup_hour, False, False)
        
        self._inc_label3 = newLabel(" : ")
        self._inc_backup_box.add(self._inc_label3, False, False)

        # Selector for the minute
        self._inc_backup_minute  = newSelector()
        self._inc_backup_minute.set_size(50, -1)
        for index in range(60):
            self._inc_backup_minute.add_item(str(index).zfill(2))
        self._inc_backup_box.add(self._inc_backup_minute, False, False)
        self._schedule.add(self._inc_backup_box, False, False)
        
        self.schedule_inc_freq_changed()
        self._inc_backup_box.set_enabled(False)
        
        self._schedule.add(newLabel("Incremental backups will create a backup of all changes that have occurred since the lastest backup, full or incremental."), False, False)
        self._schedule.add_end(newLabel("Note: backups are scheduled and executed from the target server, using the systems task scheduler."), False, False)
    def create_ui(self):
        self.set_spacing(16)
        self.content.set_padding(16)

        layer_box = mforms.newBox(True)
        layer_box.set_spacing(16)
        layer_heading = mforms.newLabel("Layer name:")
        layer_box.add(layer_heading, False, False)
        self.layer_name_lbl = mforms.newLabel("")
        layer_box.add(self.layer_name_lbl, False, False)
        self.content.add(layer_box, False, False)

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

        entry_box.add(mforms.newLabel("Destination table:"), False, True)

        self.table_name = mforms.newTextEntry()
        entry_box.add(self.table_name, True, True)

        self.content.add(entry_box, False, True)
        entry_box.show(True)

        cbox = mforms.newBox(False)

        self.column_list = newTreeNodeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.CheckColumnType, "", 40, True)
        self.column_list.add_column(mforms.StringColumnType, "Column name",
                                    300, False)
        self.column_list.end_columns()
        self.column_list.set_size(-1, 100)

        cbox.add(self.column_list, False, True)
        cbox.add(small_label("Please select columns you'd like to import"),
                 False, True)

        self.content.add(cbox, False, True)
        cbox.show(True)

        options_layer = mforms.newPanel(mforms.TitledBoxPanel)
        options_layer.set_title("Additional options")

        options_box = mforms.newBox(False)
        options_box.set_spacing(12)
        options_box.set_padding(12)

        boxfailures = mforms.newBox(False)

        self.skipfailures_chb = newCheckBox()
        self.skipfailures_chb.set_text("Skip failures")
        self.skipfailures_chb.set_active(False)

        boxfailures.add(self.skipfailures_chb, False, False)
        boxfailures.add(
            small_label(
                "if error occurs, skip it and continue processing the data"),
            False, False)
        options_box.add(boxfailures, False, False)

        boxappend = mforms.newBox(False)

        self.append_chb = newCheckBox()
        self.append_chb.set_text("Append to existing data")
        self.append_chb.set_active(False)
        boxappend.add(self.append_chb, False, False)
        boxappend.add(
            small_label(
                "append to existing table instead of creating new one"), False,
            False)
        options_box.add(boxappend, False, False)

        boxoverwrite = mforms.newBox(False)

        self.overwrite_chb = newCheckBox()
        self.overwrite_chb.set_text("Overwrite existing data")
        self.overwrite_chb.set_active(False)
        boxoverwrite.add(self.overwrite_chb, False, False)
        boxoverwrite.add(
            small_label("delete current table and recreate it empty"), False,
            False)
        options_box.add(boxoverwrite, False, False)

        options_layer.add(options_box)
        options_layer.show(True)

        self.content.add(options_layer, False, False)

        boxconvert = mforms.newBox(False)
        self.cartesian_convert_chb = newCheckBox()
        self.cartesian_convert_chb.set_text(
            "Convert data to cartesian coordinate system")
        self.cartesian_convert_chb.set_active(True)

        boxconvert.add(self.cartesian_convert_chb, False, True)
        boxconvert.add(
            small_label(
                "MySQL support only Cartesian format, leaving this checkbox in it's initial state will convert the data which may lead to data loss"
            ), False, False)

        self.content.add(boxconvert, False, True)
        self.get_info()
    def create_ui(self):
        ui_box = mforms.newBox(False)

        ui_box.add(newLabel(" "), False, True)

        self.long_status_msg = newLabel("The database server is stopped")
        self.long_status_msg.set_style(mforms.SmallStyle)

        status_message_part = newLabel("The database server instance is ")
        self.short_status_msg = newLabel("...")
        self.short_status_msg.set_color("#DD0000")

        self.start_stop_btn = newButton()
        self.start_stop_btn.set_text("Start server")
        self.start_stop_btn.add_clicked_callback(self.start_stop_clicked)
        
        self.offline_mode_btn = newButton()
        self.offline_mode_btn.set_text("Bring Offline")
        self.offline_mode_btn.add_clicked_callback(self.offline_mode_clicked)

        start_stop_hbox = newBox(True)
        start_stop_hbox.add(status_message_part, False, True)
        start_stop_hbox.add(self.short_status_msg, False, True)
        start_stop_hbox.add(self.start_stop_btn, False, True)
        start_stop_hbox.add(self.offline_mode_btn, False, True)

        if self._ctrl_be.target_version and self._ctrl_be.target_version.is_supported_mysql_version_at_least(5, 7, 5):
            self.offline_mode_btn.show(True)
        else:
            self.offline_mode_btn.show(False)

        ui_box.add(self.long_status_msg, False, True)
        ui_box.add(start_stop_hbox, False, True)

        description = newLabel("If you stop the server, neither you nor your applications can use the database and all current connections will be closed.\n")
        description.set_style(mforms.SmallStyle)
        ui_box.add(description, False, True)

        auto_start_checkbox = newCheckBox()
        auto_start_checkbox.set_text("Automatically Start Database Server on Startup")
        auto_start_checkbox.set_active(True)

        description = newLabel("You may select to have the database server start automatically whenever the computer starts up.")
        description.set_style(mforms.SmallStyle)
        description.set_wrap_text(True)

        # Right pane (log).
        heading = newLabel("\nStartup Message Log")
        heading.set_style(mforms.BoldStyle)
        ui_box.add(heading, False, True)

        self.startup_msgs_log = newTextBox(mforms.BothScrollBars)
        self.startup_msgs_log.set_name('Startup Messages Log')
        self.startup_msgs_log.set_read_only(True)
        ui_box.add(self.startup_msgs_log, True, True)

        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.update_ui()
        
        return ui_box
Example #44
0
    def create_ui(self):
        self.set_spacing(16)
        
        label = mforms.newLabel("Select destination table and additional options.")
        label.set_style(mforms.BoldInfoCaptionStyle)
        self.content.add(label, False, True)

        
        table_destination_box = mforms.newBox(False)
        table_destination_box.set_spacing(8)

        existing_table_box = mforms.newBox(True)
        existing_table_box.set_spacing(8)
        self.existing_table_radio = mforms.newRadioButton(1)
        self.existing_table_radio.set_text("Use existing table:")
        self.existing_table_radio.add_clicked_callback(self.radio_click)
        if 'table' in self.main.destination_table and self.main.destination_table['table'] is not None:
            self.existing_table_radio.set_active(True)
        existing_table_box.add(self.existing_table_radio, False, True)
        
        self.destination_table_sel = mforms.newSelector()
        self.destination_table_sel.set_size(75, -1)
        existing_table_box.add(self.destination_table_sel, True, True)
        table_destination_box.add(existing_table_box, False, True)
            
        new_table_box = mforms.newBox(True)
        new_table_box.set_spacing(8)
        self.new_table_radio = mforms.newRadioButton(1)
        self.new_table_radio.set_text("Create new table: ")
        self.new_table_radio.add_clicked_callback(self.radio_click)
        if 'table' not in self.main.destination_table or self.main.destination_table['table'] is None:
            self.new_table_radio.set_active(True)
            
        new_table_box.add(self.new_table_radio, False, True)
        self.destination_database_sel = mforms.newSelector()
        self.destination_database_sel.set_size(120, -1)
        new_table_box.add(self.destination_database_sel, False, True)
        new_table_box.add(mforms.newLabel("."), False, True)
        self.new_table_name = mforms.newTextEntry()
        new_table_box.add_end(self.new_table_name, True, True)
        table_destination_box.add(new_table_box, True, True)
        
        def set_trunc(sender):
            global truncate_table
            truncate_table = sender.get_active()
 
        self.truncate_table_cb = mforms.newCheckBox()
        self.truncate_table_cb.set_text("Truncate table before import")
        self.truncate_table_cb.set_active(truncate_table)
        self.truncate_table_cb.add_clicked_callback(lambda sender = self.truncate_table_cb: set_trunc(sender))
        table_destination_box.add(self.truncate_table_cb, False, True)
        
        def set_drop(sender):
            global drop_table
            drop_table = sender.get_active()
            
        self.drop_table_cb = mforms.newCheckBox()
        self.drop_table_cb.set_text("Drop table if exists")
        self.drop_table_cb.set_active(drop_table)
        self.drop_table_cb.add_clicked_callback(lambda sender = self.drop_table_cb: set_drop(sender))
        if self.existing_table_radio.get_active():
            self.drop_table_cb.show(False)
            self.truncate_table_cb.show(True)
        else:
            self.drop_table_cb.show(True)
            self.truncate_table_cb.show(False)
        table_destination_box.add(self.drop_table_cb, False, True)
        
        self.content.add(table_destination_box, False, True)
 def create_chkbox(row):
     chk =  mforms.newCheckBox()
     chk.set_active(True)
     chk.add_clicked_callback(lambda checkbox = chk, output = row: operator.setitem(output, 'active', True if checkbox.get_active() else False))
     return chk
    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")
Example #47
0
    def create_ui(self):
        self.suspend_layout()

        if not self.server_profile.admin_enabled:
            self.add(no_remote_admin_warning_label(self.server_profile), False, True)
            self.resume_layout()
            return

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

        # Left pane (start/stop).
        self.heading = make_panel_header("title_startup.png", self.server_profile.name, "Startup / Shutdown MySQL Server")
        self.add(self.heading, False, True)

        self.add(newLabel(" "), False, False)

        self.long_status_msg = newLabel("The database server is stopped")
        self.long_status_msg.set_style(mforms.SmallStyle)

        status_message_part = newLabel("The database server instance is ")
        self.short_status_msg = newLabel("...")
        self.short_status_msg.set_color("#DD0000")

        self.start_stop_btn = newButton()
        self.start_stop_btn.set_text("Start server")
        self.start_stop_btn.add_clicked_callback(self.start_stop_clicked)

        start_stop_hbox = newBox(True)
        start_stop_hbox.add(status_message_part, False, True)
        start_stop_hbox.add(self.short_status_msg, False, True)
        start_stop_hbox.add(newLabel("  "), False, False)
        start_stop_hbox.add(self.start_stop_btn, False, False)

        self.add(self.long_status_msg, False, True)
        self.add(start_stop_hbox, False, False)

        description = newLabel("If you stop the server, you and your applications will not be able to use the Database and all current connections will be closed\n")
        description.set_style(mforms.SmallStyle)
        self.add(description, False, False)

        auto_start_checkbox = newCheckBox()
        auto_start_checkbox.set_text("Automatically Start Database Server on Startup")
        auto_start_checkbox.set_active(True)

        description = newLabel("You may select to have the Database server start automatically whenever the computer starts up.")
        description.set_style(mforms.SmallStyle)
        description.set_wrap_text(True)

        # Right pane (log).
        heading = newLabel("\nStartup Message Log")
        heading.set_style(mforms.BoldStyle)
        self.add(heading, False, True)

        self.startup_msgs_log = newTextBox(mforms.BothScrollBars)
        self.startup_msgs_log.set_name('StartupMessagesLog')
        self.startup_msgs_log.set_read_only(True)
        self.add(self.startup_msgs_log, True, True)

        button_box = newBox(True)
        self.refresh_button = newButton()
        self.refresh_button.set_size(150, -1)
        self.refresh_button.set_text("Refresh Status")
        self.refresh_button.add_clicked_callback(lambda:self.refresh(True))
        button_box.add(self.refresh_button, False, False)

        self.copy_to_clipboard_button = newButton()
        self.copy_to_clipboard_button.set_size(150, -1)
        self.copy_to_clipboard_button.set_text("Copy to Clipboard")
        self.copy_to_clipboard_button.add_clicked_callback(self.copy_to_clipboard)
        button_box.add_end(self.copy_to_clipboard_button, False, False)

        self.clear_messages_button = newButton()
        self.clear_messages_button.set_size(150, -1)
        self.clear_messages_button.set_text("Clear Messages")
        self.clear_messages_button.add_clicked_callback(self.clear_messages)
        button_box.add_end(self.clear_messages_button, False, False)
        self.add(button_box, False, True)

        self.resume_layout()

        self.ctrl_be.add_me_for_event("server_started", self)
        self.ctrl_be.add_me_for_event("server_stopped", self)
Example #48
0
    def __init__(self, types_to_display, database_objects, ui_settings={}):
        super(DatabaseObjectSelector, self).__init__(False)
        self.database_objects = database_objects
        self.supported_object_types = types_to_display

        self.ui_settings = {
            'tables': {
                'icon': 'db.Table.many.32x32.png',
                'small_icon': 'db.Table.16x16.png',
                'group_label': 'Migrate Table objects',
                'group_selected': True,
                'status_text': '%(total)d total, %(selected)d selected',
                'show_details': False,
            },
            'views': {
                'icon': 'db.View.many.32x32.png',
                'small_icon': 'db.View.16x16.png',
                'group_label': 'Migrate View objects',
                'group_selected': True,
                'status_text': '%(total)d total, %(selected)d selected',
                'show_details': False,
            },
            'routines': {
                'icon': 'db.Routine.many.32x32.png',
                'small_icon': 'db.Routine.16x16.png',
                'group_label': 'Migrate Routine objects',
                'group_selected': True,
                'status_text': '%(total)d total, %(selected)d selected',
                'show_details': False,
            },
            'routineGroups': {
                'icon': 'db.RoutineGroup.48x48.png',
                'small_icon': 'db.RoutineGroup.16x16.png',
                'group_label': 'Migrate Routine Group/Package objects',
                'group_selected': True,
                'status_text': '%(total)d total, %(selected)d selected',
                'show_details': False,
            },
            'synonyms': {
                'icon': 'grt_object.png',
                'small_icon': 'grt_object.png',
                'group_label': 'Migrate Synonym objects',
                'group_selected': True,
                'status_text': '%(total)d total, %(selected)d selected',
                'show_details': False,
            },
            'structuredTypes': {
                'icon': 'grt_object.png',
                'small_icon': 'grt_object.png',
                'group_label': 'Migrate Structured Type objects',
                'group_selected': True,
                'status_text': '%(total)d total, %(selected)d selected',
                'show_details': False,
            },
            'sequences': {
                'icon': 'grt_object.png',
                'small_icon': 'grt_object.png',
                'group_label': 'Migrate Sequence objects',
                'group_selected': True,
                'status_text': '%(total)d total, %(selected)d selected',
                'show_details': False,
            },
        }

        # Update the ui settings dict with the custom settings supplied by the user (if any):
        if isinstance(ui_settings, dict):
            for key, value in list(ui_settings.items()):
                if key not in self.ui_settings or not isinstance(value, dict):
                    continue
                self.ui_settings[key].update(value)

        # Create UI:
        self.set_padding(8)
        self.set_spacing(8)

        self.ui = {}
        for group in self.supported_object_types:
            if group not in self.database_objects or group not in self.ui_settings:
                continue
            self.ui[group] = {}
            group_objects = self.database_objects[group]

            group_panel = mforms.newPanel(mforms.BorderedPanel)
            group_box = mforms.newBox(False)
            group_box.set_padding(8)
            group_box.set_spacing(8)

            header_box = mforms.Box(True)
            header_box.set_spacing(8)

            icon = mforms.newImageBox()
            icon.set_image(self.ui_settings[group]['icon'])
            header_box.add(icon, False, True)

            text_box = mforms.Box(False)
            group_selector = mforms.newCheckBox()
            group_selector.set_text(self.ui_settings[group]['group_label'])
            group_selector.set_active(
                bool(self.ui_settings[group]['group_selected']))
            group_selector.add_clicked_callback(
                functools.partial(self.group_checkbox_clicked, group=group))
            text_box.add(group_selector, False, True)
            info_label = mforms.newLabel(
                self.ui_settings[group]['status_text'] % {
                    'total':
                    len(group_objects),
                    'selected':
                    len(group_objects)
                    if self.ui_settings[group]['group_selected'] else 0
                })
            info_label.set_style(mforms.SmallHelpTextStyle)
            text_box.add(info_label, False, True)
            header_box.add(text_box, False, True)

            show_details = self.ui_settings[group]['show_details']
            self.ui_settings[group]['_showing_details'] = show_details
            filter_button = mforms.newButton()
            filter_button.set_text(
                'Hide Selection' if show_details else 'Show Selection')
            filter_button.set_enabled(
                bool(self.ui_settings[group]['group_selected']))
            filter_button.add_clicked_callback(
                functools.partial(self.filter_button_clicked, group=group))
            header_box.add_end(filter_button, False, True)

            group_box.add(header_box, False, True)

            # The invisible stuff:
            if len(group_objects) > 0:
                box = mforms.newBox(True)
                search_entry = mforms.newTextEntry(mforms.SearchEntry)
                search_entry.set_name("Search Entry")
                search_entry.set_placeholder_text(
                    "Filter objects (wildcards chars * and ? are allowed)")
                search_entry.add_changed_callback(
                    functools.partial(self.search_entry_changed, group=group))
                box.add(search_entry, False, True)
                group_box.add(box, True, True)
                search_entry.set_size(350, -1)

                filter_container = mforms.newBox(True)
                filter_container.set_spacing(8)

                available_list = mforms.newTreeView(mforms.TreeFlatList)
                available_list.set_name("Available List")
                available_list.add_column(mforms.IconColumnType,
                                          'Available Objects', 300, False)
                available_list.end_columns()
                available_list.set_selection_mode(mforms.TreeSelectMultiple)
                available_list.set_allow_sorting(False)
                filter_container.add(available_list, True, True)

                control_box = mforms.newBox(False)
                control_box.set_padding(0, 30, 0, 30)
                control_box.set_spacing(4)
                add_button = mforms.newButton()
                add_button.set_text('>')
                add_button.enable_internal_padding(False)
                add_button.add_clicked_callback(
                    functools.partial(self.move_button_clicked,
                                      group=group,
                                      operation='add'))
                add_button.set_size(90, 30)
                control_box.add(add_button, False)
                remove_button = mforms.newButton()
                remove_button.set_text('<')
                remove_button.enable_internal_padding(False)
                remove_button.add_clicked_callback(
                    functools.partial(self.move_button_clicked,
                                      group=group,
                                      operation='remove'))
                remove_button.set_size(90, 30)
                control_box.add(remove_button, False, True)
                add_all_button = mforms.newButton()
                add_all_button.set_text('>>')
                add_all_button.enable_internal_padding(False)
                add_all_button.add_clicked_callback(
                    functools.partial(self.move_button_clicked,
                                      group=group,
                                      operation='add_all'))
                add_all_button.set_size(90, 30)
                control_box.add(add_all_button, False, True)
                remove_all_button = mforms.newButton()
                remove_all_button.set_text('<<')
                remove_all_button.enable_internal_padding(False)
                remove_all_button.add_clicked_callback(
                    functools.partial(self.move_button_clicked,
                                      group=group,
                                      operation='remove_all'))
                remove_all_button.set_size(90, 30)
                control_box.add(remove_all_button, False)
                filter_container.add(control_box, False, True)

                selected_list = mforms.newTreeView(mforms.TreeFlatList)
                selected_list.set_name("Selected List")
                selected_list.add_column(mforms.IconColumnType,
                                         'Objects to Migrate', 300, False)
                selected_list.end_columns()
                selected_list.set_selection_mode(mforms.TreeSelectMultiple)
                selected_list.set_allow_sorting(False)
                for item in sorted(group_objects):
                    node = selected_list.add_node()
                    node.set_icon_path(0,
                                       self.ui_settings[group]['small_icon'])
                    node.set_string(0, item)
                filter_container.add(selected_list, True, True)

                group_box.add(filter_container, True, True)

                filter_container.show(bool(show_details))

                self.ui[group].update({
                    'filter_container': filter_container,
                    'available_list': available_list,
                    'selected_list': selected_list,
                    'search_entry': search_entry,
                })
            else:  # Empty object list
                filter_button.set_enabled(False)

            self.ui[group].update({
                'icon': icon,
                'group_selector': group_selector,
                'group_panel': group_panel,
                'info_label': info_label,
                'filter_button': filter_button,
                'all_objects': set(group_objects),
                'has_elements': bool(len(group_objects)),
                'available': set(),
                'selected': set(group_objects),
                'objects_passing_filter': set(group_objects),
            })
            group_panel.add(group_box)
            self.add(group_panel, False, True)
Example #49
0
    def place_control(self, ctrl_def, table, row):
      ctrl = None
      ctype = ctrl_def['type']
      name = ctrl_def['name']

      enabled = newCheckBox()
      enabled.set_text(ctrl_def['caption'])
      enabled.set_size(200, -1) # Use a fixed fix to make all tables align their columns properly. Must be larger than the largest text, to make it work.
      enabled.set_tooltip(ctrl_def['name'])

      # place_control creates control as ctrl_def describes. Reference to a created control is placed 
      # to map of controls. That is done in order to access controls via option name
      if ctype == "checkbox" or ctype == "boolean":
        ctrl = ('chk', (enabled, enabled), ctrl_def)
        self.opt2ctrl_map[name] = ctrl
        enabled.set_active(False)
        #label = newLabel(" ")
        #table.add(label, 1, 2, row, row+1, HExpandFlag | HFillFlag)
      elif ctype == 'textedit' or ctype == 'string' or ctype == 'set':
        te = self.create_textedit(name, ctrl_def)
        table.add(te, 1, 2, row, row+1, HExpandFlag | HFillFlag)
        ctrl = ('txt', (enabled, te), ctrl_def)
        self.opt2ctrl_map[name] = ctrl
      elif ctype == "directory" or ctype == "filename" or ctype == "dirname":
        (dir_box, te, btn) = self.create_dir_file_edit(name, ctrl_def)
        table.add(dir_box, 1, 2, row, row + 1, HExpandFlag | HFillFlag)
        te.add_changed_callback(lambda: self.control_action(name))
        ctrl = ('dir', (enabled, te, btn), ctrl_def)
        self.opt2ctrl_map[name] = ctrl
      elif ctype == "numeric" or ctype == "spinedit":
        #(spin_box, te, unitcontrol, unit_items) = self.create_numeric(name, ctrl_def)
        #ctrl = ('spn', (enabled, te, unitcontrol, unit_items), ctrl_def)
        te = self.create_numeric(name, ctrl_def)
        #ctrl = ('spn', (enabled, te), ctrl_def)
        ctrl = ('txt', (enabled, te), ctrl_def)
        self.opt2ctrl_map[name] = ctrl
        #table.add(spin_box, 1, 2, row, row + 1, HExpandFlag | HFillFlag)
        table.add(te, 1, 2, row, row + 1, HExpandFlag | HFillFlag)
      elif ctype == "dropdownbox" or ctype == 'dropdownboxentry':
        if 'choice' not in ctrl_def:
          te = newTextEntry()
          te.set_enabled(False)
          te.add_changed_callback(lambda: self.control_action(name))
          table.add(te, 1, 2, row, row+1, HExpandFlag | HFillFlag)
          ctrl = ('txt', (enabled, te), ctrl_def)
          self.opt2ctrl_map[name] = ctrl
        else:
          (dropbox, items) = self.create_dropdownbox(name, ctrl_def, ctype)
          table.add(dropbox, 1, 2, row, row + 1, HExpandFlag | HFillFlag)
          ctrl = ('drp', (enabled, dropbox, items), ctrl_def)
          self.opt2ctrl_map[name] = ctrl

      if CATOPTS is None:
        table.add(enabled, 0, 1, row, row + 1, HFillFlag)
        enabled.add_clicked_callback(lambda: self.enabled_checkbox_click(name))
      else:
        catbox = newBox(True)
        cat = newSelector(mforms.SelectorCombobox)
        for item in cat_sec:
          cat.add_item(item)
        grp = newSelector(mforms.SelectorCombobox)
        for item in cat_grp:
          grp.add_item(item)
        cat.add_changed_callback(lambda : handle_cat_opt(cat, grp, ctrl_def['name']))
        grp.add_changed_callback(lambda : handle_cat_opt(cat, grp, ctrl_def['name']))
        catbox.add(cat, True, True)
        catbox.add(grp, True, True)
        catbox.add(enabled, True, True)
        table.add(catbox, 0, 1, row, row + 1, HExpandFlag | HFillFlag)

      return ctrl
    def create_ui(self):
        self.set_spacing(16)
        layer_box = mforms.newBox(True)
        layer_box.set_spacing(8)
        layer_heading = mforms.newLabel("Layer name:")
        layer_box.add(layer_heading, False, False)
        self.layer_name_lbl = mforms.newLabel("")
        layer_box.add(self.layer_name_lbl, False, False)
        self.content.add(layer_box, False, False)

        epsg_box = mforms.newBox(True)
        epsg_box.set_spacing(8)
        epsg_box_heading = mforms.newLabel("EPSG:")
        epsg_box.add(epsg_box_heading, False, False)
        self.epsg_lbl = mforms.newLabel("")
        epsg_box.add(self.epsg_lbl, False, False)
        self.content.add(epsg_box, False, False)

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

        entry_box.add(mforms.newLabel("Destination table:"), False, True)

        self.table_name = mforms.newTextEntry()
        entry_box.add(self.table_name, True, True)

        self.content.add(entry_box, False, True)
        entry_box.show(True)

        cbox = mforms.newBox(False)

        self.column_list = newTreeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.CheckColumnType, "", 40, True)
        self.column_list.add_column(mforms.StringColumnType, "Column name",
                                    300, False)
        self.column_list.end_columns()
        self.column_list.set_size(-1, 150)

        cbox.add(small_label("Please select the columns you want to import:"),
                 False, True)
        cbox.add(self.column_list, False, True)

        self.content.add(cbox, False, True)
        cbox.show(True)

        options_layer = mforms.newPanel(mforms.TitledBoxPanel)
        options_layer.set_title("Additional options")

        options_box = mforms.newBox(False)
        options_box.set_spacing(12)
        options_box.set_padding(12)

        boxfailures = mforms.newBox(False)

        self.skipfailures_chb = newCheckBox()
        self.skipfailures_chb.set_text("Skip failures")
        self.skipfailures_chb.set_active(False)

        boxfailures.add(self.skipfailures_chb, False, False)
        boxfailures.add(
            small_label(
                "If an error occurs ignore it and continue processing data."),
            False, False)
        options_box.add(boxfailures, False, False)

        boxappend = mforms.newBox(False)

        self.append_chb = newCheckBox()
        self.append_chb.set_text("Append to existing data")
        self.append_chb.set_active(False)
        boxappend.add(self.append_chb, False, False)
        boxappend.add(
            small_label(
                "Append to existing table instead of creating a new one."),
            False, False)
        options_box.add(boxappend, False, False)

        boxoverwrite = mforms.newBox(False)

        self.overwrite_chb = newCheckBox()
        self.overwrite_chb.set_text("Overwrite existing data")
        self.overwrite_chb.set_active(False)

        self.append_chb.add_clicked_callback(
            lambda checkbox1=self.append_chb, checkbox2=self.overwrite_chb:
            self.one_check_only(checkbox1, checkbox2))
        self.overwrite_chb.add_clicked_callback(
            lambda checkbox2=self.append_chb, checkbox1=self.overwrite_chb:
            self.one_check_only(checkbox1, checkbox2))
        boxoverwrite.add(self.overwrite_chb, False, False)
        boxoverwrite.add(
            small_label("Drop the selected table and recreate it."), False,
            False)
        options_box.add(boxoverwrite, False, False)

        if self.support_spatial_index:
            boxspatial = mforms.newBox(False)
            self.spatial_index_chb = newCheckBox()
            self.spatial_index_chb.set_text("Create spatial index")
            self.spatial_index_chb.set_active(False)
            boxspatial.add(self.spatial_index_chb, False, False)
            boxspatial.add(
                small_label(
                    "import will make spatial index around geometry column"),
                False, False)
            options_box.add(boxspatial, False, False)

        options_layer.add(options_box)
        options_layer.show(True)

        self.content.add(options_layer, False, False)

        boxconvert = mforms.newBox(False)
        entry_box = mforms.newBox(True)
        entry_box.set_spacing(8)
        entry_box.add(mforms.newLabel("Convert data to the following EPSG:"),
                      False, True)
        self.convert_to_epsg = mforms.newTextEntry()
        entry_box.add(self.convert_to_epsg, False, False)
        boxconvert.add(entry_box, True, True)
        boxconvert.add(
            small_label("leave empty to import the data with no conversion"),
            False, False)

        self.content.add(boxconvert, False, True)
        self.get_info()
  def __init__(self, catalog):
    mforms.Form.__init__(self, None, mforms.FormNone)

    self.catalog = catalog

    self.set_title("Create Relationships for Tables")

    box = mforms.newBox(False)
    self.set_content(box)
    box.set_padding(12)
    box.set_spacing(12)

    label = mforms.newLabel(
"""This will automatically create foreign keys for tables that match
a certain column naming pattern, allowing you to visualize relationships 
between MyISAM tables.

To use, fill the Column Pattern field with the naming convention used for
columns that are meant to be used as foreign keys. The %(table)s and %(pk)s
variable names will be substituted with the referenced table values.""")
    box.add(label, False, True)

    hbox = mforms.newBox(True)
    hbox.set_spacing(12)
    box.add(hbox, False, True)

    label = mforms.newLabel("Column Pattern:")
    hbox.add(label, False, True)
    self.pattern = mforms.newTextEntry()
    hbox.add(self.pattern, True, True)
    self.matchType = mforms.newCheckBox()
    self.matchType.set_text("Match column types")
    hbox.add(self.matchType, False, True)
    self.matchType.set_active(True)
    search = mforms.newButton()
    search.set_text("Preview Matches")
    search.add_clicked_callback(self.findMatches)
    hbox.add(search, False, True)

    self.pattern.set_value("%(table)s_id")

    self.candidateTree = mforms.newTreeView(mforms.TreeShowHeader)
    self.candidateTree.add_column(mforms.StringColumnType, "From Table", 100, False)
    self.candidateTree.add_column(mforms.StringColumnType, "Column", 100, False)
    self.candidateTree.add_column(mforms.StringColumnType, "Type", 100, False)
    self.candidateTree.add_column(mforms.StringColumnType, "To Table", 100, False)
    self.candidateTree.add_column(mforms.StringColumnType, "Column", 100, False)
    self.candidateTree.add_column(mforms.StringColumnType, "Type", 100, False)
    self.candidateTree.end_columns()
    box.add(self.candidateTree, True, True)

    hbox = mforms.newBox(True)
    hbox.set_spacing(12)
    self.matchCount = mforms.newLabel("")
    hbox.add(self.matchCount, False, True)
    self.cancelButton = mforms.newButton()
    self.cancelButton.set_text("Cancel")
    hbox.add_end(self.cancelButton, False, True)
    self.okButton = mforms.newButton()
    self.okButton.set_text("Create FKs")
    hbox.add_end(self.okButton, False, True)
    self.okButton.add_clicked_callback(self.createFKs)
    box.add(hbox, False, True)

    self.set_size(700, 600)
    def create_ui(self):
        self.set_spacing(16)
        self.content.set_padding(16)
        
        layer_box = mforms.newBox(True)
        layer_box.set_spacing(16)
        layer_heading = mforms.newLabel("Layer name:")
        layer_box.add(layer_heading, False, False)
        self.layer_name_lbl = mforms.newLabel("")
        layer_box.add(self.layer_name_lbl, False, False)
        self.content.add(layer_box, False, False)

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

        entry_box.add(mforms.newLabel("Destination table:"), False, True)

        self.table_name = mforms.newTextEntry()
        entry_box.add(self.table_name, True, True)
        
        self.content.add(entry_box, False, True)
        entry_box.show(True)

        cbox = mforms.newBox(False)

        self.column_list = newTreeNodeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.CheckColumnType, "", 40, True)
        self.column_list.add_column(mforms.StringColumnType, "Column name", 300, False)
        self.column_list.end_columns()
        self.column_list.set_size(-1, 100)

        cbox.add(self.column_list, False, True)
        cbox.add(small_label("Please select columns you'd like to import"), False, True)

        self.content.add(cbox, False, True)
        cbox.show(True)
        
        options_layer = mforms.newPanel(mforms.TitledBoxPanel)
        options_layer.set_title("Additional options")
        
        options_box = mforms.newBox(False)
        options_box.set_spacing(12)
        options_box.set_padding(12)
        
        boxfailures = mforms.newBox(False)
        
        self.skipfailures_chb = newCheckBox()
        self.skipfailures_chb.set_text("Skip failures");
        self.skipfailures_chb.set_active(False)
        
        boxfailures.add(self.skipfailures_chb, False, False)
        boxfailures.add(small_label("if error occurs, skip it and continue processing the data"), False, False)
        options_box.add(boxfailures, False, False)
        
        boxappend = mforms.newBox(False)
        
        self.append_chb = newCheckBox()
        self.append_chb.set_text("Append to existing data");
        self.append_chb.set_active(False)
        boxappend.add(self.append_chb, False, False)
        boxappend.add(small_label("append to existing table instead of creating new one"), False, False)
        options_box.add(boxappend, False, False)
        
        boxoverwrite = mforms.newBox(False)
        
        self.overwrite_chb = newCheckBox()
        self.overwrite_chb.set_text("Overwrite existing data");
        self.overwrite_chb.set_active(False)
        boxoverwrite.add(self.overwrite_chb, False, False)
        boxoverwrite.add(small_label("delete current table and recreate it empty"), False, False)
        options_box.add(boxoverwrite, False, False)
        
        options_layer.add(options_box)
        options_layer.show(True)
        
        self.content.add(options_layer, False, False)

        boxconvert = mforms.newBox(False)
        self.cartesian_convert_chb = newCheckBox()
        self.cartesian_convert_chb.set_text("Convert data to cartesian coordinate system");
        self.cartesian_convert_chb.set_active(True)

        boxconvert.add(self.cartesian_convert_chb, False, True)
        boxconvert.add(small_label("MySQL supports only Cartesian format. Leaving this checkbox in its initial state will convert the data which may lead to data loss"), False, False)
        
        self.content.add(boxconvert, False, True)
        self.get_info()
    def create_ui(self):
        dprint_ex(4, "Enter")
        self.suspend_layout()

        self.heading = make_panel_header("title_connections.png", self.instance_info.name, "Client Connections")
        self.add(self.heading, False, False)

        self.warning = not_running_warning_label()
        self.add(self.warning, False, True)

        self.connection_list = newTreeNodeView(mforms.TreeDefault|mforms.TreeFlatList|mforms.TreeAltRowColors)
        self.connection_list.add_column(mforms.LongIntegerColumnType, "Id", 50, False)
        self.connection_list.add_column(mforms.StringColumnType, "User", 80, False)
        self.connection_list.add_column(mforms.StringColumnType, "Host", 120, False)
        self.connection_list.add_column(mforms.StringColumnType, "DB", 100, False)
        self.connection_list.add_column(mforms.StringColumnType, "Command", 80, False)
        self.connection_list.add_column(mforms.LongIntegerColumnType, "Time", 60, False)
        self.connection_list.add_column(mforms.StringColumnType, "State", 80, False)
        self.info_column = self.connection_list.add_column(mforms.StringColumnType, "Info", 300, False)
        self.connection_list.end_columns()
        self.connection_list.set_allow_sorting(True)
        
        self.connection_list.add_changed_callback(weakcb(self, "connection_selected"))
        
        #self.set_padding(8)
        self.add(self.connection_list, True, True)
        
        self.button_box = box = newBox(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")
        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")
        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_item_with_title("Copy Info", self.copy_selected, "copy_selected")
        self._menu.add_item_with_title("Show in Editor", self.edit_selected, "edit_selected")
        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.hide_sleep_connections = newCheckBox()
        self.hide_sleep_connections.set_text('Hide sleeping connections')
        self.hide_sleep_connections.add_clicked_callback(self.refresh)
        box.add(self.hide_sleep_connections, False, True)
        
        self.add(box, False, True)
        
        self.resume_layout()
        
        self.connection_selected()
        dprint_ex(4, "Leave")
    def create_ui(self):
        self.content.set_spacing(4)
        self.content.add(
            mforms.newLabel(
                "Review and edit migrated objects. You can manually edit the generated SQL before applying them to the target database."
            ), False, True)

        hbox = mforms.newBox(True)
        self.tree_head_label = mforms.newLabel("Migrated Objects")
        hbox.add(self.tree_head_label, False, False)
        self._filter = mforms.newSelector()
        self._filter.add_items(
            ["Migration Problems", "All Objects", "Column Mappings"])
        self._filter.add_changed_callback(self._filter_changed)
        hbox.add_end(self._filter, False, True)
        hbox.add_end(mforms.newLabel("View:"), False, False)
        self.content.add(hbox, False, True)

        self._no_errors_text = "No migration problems found. %d warning(s).\nUse the View pulldown menu to review all objects."
        self._no_errors = mforms.newLabel(
            ''
        )  # Label text will be set later when the warning count is calculated
        self._no_errors.set_style(mforms.BigStyle)
        self._no_errors.set_text_align(mforms.MiddleLeft)
        self.content.add(self._no_errors, True, True)

        self._tree = mforms.newTreeNodeView(mforms.TreeDefault)
        self._tree.add_column(mforms.IconStringColumnType, "Source Object",
                              200, False)
        self._tree.add_column(mforms.IconStringColumnType, "Target Object",
                              200, True)
        self._tree.add_column(mforms.IconStringColumnType, "Migration Message",
                              300, False)
        self._tree.end_columns()
        self._tree.add_changed_callback(self._selection_changed)
        self.content.add(self._tree, True, True)
        self._tree.set_cell_edited_callback(self._cell_edited)

        self._all_menu = mforms.newContextMenu()
        self._all_menu.add_will_show_callback(self.all_menu_will_show)
        self._all_menu.add_check_item_with_title("Skip Object",
                                                 self.skip_object,
                                                 "skip_object")

        self._tree.set_context_menu(self._all_menu)

        self._columns = mforms.newTreeNodeView(mforms.TreeShowColumnLines
                                               | mforms.TreeShowRowLines
                                               | mforms.TreeFlatList)
        self.COL_SOURCE_SCHEMA = self._columns.add_column(
            mforms.StringColumnType, "Source Schema", 100, False)
        self.COL_SOURCE_TABLE = self._columns.add_column(
            mforms.IconStringColumnType, "Source Table", 100, False)
        self.COL_SOURCE_COLUMN = self._columns.add_column(
            mforms.IconStringColumnType, "Source Column", 100, False)
        self.COL_SOURCE_TYPE = self._columns.add_column(
            mforms.StringColumnType, "Source Type", 100, False)
        self.COL_SOURCE_FLAGS = self._columns.add_column(
            mforms.StringColumnType, "Source Flags", 100, False)
        self.COL_SOURCE_NOTNULL = self._columns.add_column(
            mforms.CheckColumnType, "NN", 25, False)
        self.COL_SOURCE_DEFAULT = self._columns.add_column(
            mforms.StringColumnType, "Source Default Value", 100, False)
        self.COL_SOURCE_COLLATION = self._columns.add_column(
            mforms.StringColumnType, "Source Collation", 100, False)
        self.COL_TARGET_SCHEMA = self._columns.add_column(
            mforms.StringColumnType, "Target Schema", 100, False)
        self.COL_TARGET_TABLE = self._columns.add_column(
            mforms.IconStringColumnType, "Target Table", 100, False)
        self.COL_TARGET_COLUMN = self._columns.add_column(
            mforms.IconStringColumnType, "Target Column", 100, True)
        self.COL_TARGET_TYPE = self._columns.add_column(
            mforms.StringColumnType, "Target Type", 100, True)
        self.COL_TARGET_FLAGS = self._columns.add_column(
            mforms.StringColumnType, "Target Flags", 100, True)
        self.COL_TARGET_AI = self._columns.add_column(mforms.CheckColumnType,
                                                      "AI", 25, True)
        self.COL_TARGET_NOTNULL = self._columns.add_column(
            mforms.CheckColumnType, "NN", 25, True)
        self.COL_TARGET_DEFAULT = self._columns.add_column(
            mforms.StringColumnType, "Target Default Value", 100, True)
        self.COL_TARGET_COLLATION = self._columns.add_column(
            mforms.StringColumnType, "Target Collation", 100, True)
        self.COL_MESSAGE = self._columns.add_column(
            mforms.IconStringColumnType, "Migration Message", 300, False)
        self._columns.end_columns()
        self._columns.set_allow_sorting(True)
        self._columns.set_selection_mode(mforms.TreeSelectMultiple)
        self._columns.add_changed_callback(self._selection_changed)
        self.content.add(self._columns, True, True)
        self._columns.set_cell_edited_callback(self._columns_cell_edited)
        self._columns.show(False)

        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self._menu.add_item_with_title(
            "Set Target Type of Selected Columns...", self.set_target_type,
            "set_target_type")
        self._menu.add_item_with_title("Find and Replace Target Type...",
                                       self.replace_target_type,
                                       "replace_target_type")
        self._menu.add_item_with_title("Find and Replace Target Flags...",
                                       self.replace_target_flags,
                                       "replace_target_flags")
        self._menu.add_item_with_title(
            "Find and Replace Target Default Value...",
            self.replace_target_default_value, "replace_target_default_value")
        self._menu.add_item_with_title("Find and Replace Target Collation...",
                                       self.replace_target_collation,
                                       "replace_target_collation")
        self._columns.set_context_menu(self._menu)

        self.help_label = mforms.newLabel(
            "You can rename target schemas and tables, and change column definitions by clicking them once selected."
        )
        self.help_label.set_style(mforms.SmallStyle)
        self.content.add(self.help_label, False, True)

        self._advbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._advbox.set_title("SQL CREATE Script for Selected Object")
        box = mforms.newBox(True)
        self._code = mforms.newCodeEditor()
        self._code.set_language(mforms.LanguageMySQL)
        self._code.add_changed_callback(self._code_changed)
        box.add(self._code, True, True)
        vbox = mforms.newBox(False)
        vbox.set_padding(12)
        vbox.set_spacing(8)

        self._lock_check = mforms.newCheckBox()
        self._lock_check.set_text("Lock edited SQL")
        self._lock_check.set_tooltip(
            "Lock the SQL code to the edited one, preventing automatic regenerations from discarding changes made directly to the SQL script."
        )
        self._lock_check.add_clicked_callback(self._lock_clicked)
        vbox.add(self._lock_check, False, True)

        self._comment_check = mforms.newCheckBox()
        self._comment_check.set_text("Comment out")
        self._comment_check.set_tooltip(
            "Mark the object to be commented out on the generated script, making it not get created in the target server."
        )
        self._comment_check.add_clicked_callback(self._comment_clicked)
        vbox.add(self._comment_check, False, True)

        self._sql_outdated_label = mforms.newLabel("Code is outdated")
        self._sql_outdated_label.show(False)
        self._sql_outdated_label.set_tooltip(
            "The locked SQL code seems to be outdated compared to a newer, automatically generated one. Unlocking the object will update it, but your changes will be lost."
        )
        vbox.add(self._sql_outdated_label, False, True)

        self._revert_btn = mforms.newButton()
        self._revert_btn.set_text("Discard Changes")
        vbox.add_end(self._revert_btn, False, True)
        self._revert_btn.add_clicked_callback(self._discard_clicked)

        self._apply_btn = mforms.newButton()
        self._apply_btn.set_text("Apply Changes")
        vbox.add_end(self._apply_btn, False, True)
        self._apply_btn.add_clicked_callback(self._apply_clicked)
        box.add(vbox, False, True)

        self._advbox.add(box)
        self._advbox.set_size(-1, 200)
        self._advbox_shown = True
        self.go_advanced()  # toggle to hide

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

        self._filter_errors = False
        self._filter_changed()
    def create_ui(self):
        self.suspend_layout()

        if not self.server_profile.admin_enabled:
            self.add(no_remote_admin_warning_label(self.server_profile), False, True)
            self.resume_layout()
            return

        self.main_view.ui_profile.apply_style(self, 'page')
        self.set_padding(8) # TODO check padding

        # Top layout structure.
        content = newBox(False)
        self.add(content, True, True)

        # A spacer at the bottom of the page.
        spacer = newBox(True)
        spacer.set_size(-1, 40)
        self.add(spacer, False, True)

        # Left pane (start/stop).
        heading = newLabel("Database Server Status")
        heading.set_style(mforms.BoldStyle)
        content.add(heading, False, True)

        left_pane = newBox(False)
        left_pane.set_spacing(8)

        self.long_status_msg = newLabel("The database server is stopped")
        self.long_status_msg.set_style(mforms.SmallStyle)
        left_pane.add(self.long_status_msg, False, True)

        status_message_part = newLabel("The database server instance is ")
        self.short_status_msg = newLabel("...")
        self.short_status_msg.set_color("#DD0000")

        self.start_stop_btn = newButton()
        self.start_stop_btn.set_text("Start server")
        self.start_stop_btn.add_clicked_callback(self.start_stop_clicked)

        start_stop_hbox = newBox(True)
        start_stop_hbox.add(status_message_part, False, True)
        start_stop_hbox.add(self.short_status_msg, False, True)
        start_stop_hbox.add(newLabel("  "), False, False)
        start_stop_hbox.add(self.start_stop_btn, False, False)
        left_pane.add(start_stop_hbox, False, False)

        left_pane.add(self.long_status_msg, False, False)
        left_pane.add(start_stop_hbox, False, False)

        description = newLabel("If you stop the server, you and your applications will not be able to use the Database and all current connections will be closed")
        description.set_style(mforms.SmallStyle)
        left_pane.add(description, False, False)

        separator = newImageBox()
        separator.set_image("options-horizontal-separator.png")
        left_pane.add(separator, False, True)

        auto_start_checkbox = newCheckBox()
        auto_start_checkbox.set_text("Automatically Start Database Server on Startup")
        auto_start_checkbox.set_active(True)

        description = newLabel("You may select to have the Database server start automatically whenever the computer starts up.")
        description.set_style(mforms.SmallStyle)
        description.set_wrap_text(True)

        content.add(left_pane, False, True)

        # Right pane (log).
        heading = newLabel("Startup Message Log")
        heading.set_style(mforms.BoldStyle)
        content.add(heading, False, True)

        right_pane = newBox(False)    
        right_pane.set_spacing(8)

        self.startup_msgs_log = newTextBox(mforms.BothScrollBars)
        self.startup_msgs_log.set_read_only(True)
        right_pane.add(self.startup_msgs_log, True, True)

        button_box = newBox(True)
        self.refresh_button = newButton()
        self.refresh_button.set_text("Refresh Status")
        self.refresh_button.add_clicked_callback(lambda:self.refresh(2))
        button_box.add(self.refresh_button, False, False)

        self.copy_to_clipboard_button = newButton()
        self.copy_to_clipboard_button.set_size(150, -1)
        self.copy_to_clipboard_button.set_text("Copy to Clipboard")
        self.copy_to_clipboard_button.add_clicked_callback(self.copy_to_clipboard)
        button_box.add_end(self.copy_to_clipboard_button, False, False)

        self.clear_messages_button = newButton()
        self.clear_messages_button.set_size(150, -1)
        self.clear_messages_button.set_text("Clear Messages")
        self.clear_messages_button.add_clicked_callback(self.clear_messages)
        button_box.add_end(self.clear_messages_button, False, False)
        right_pane.add(button_box, False, True)

        content.add(right_pane, True, True)

        self.resume_layout()

        self.ctrl_be.add_me_for_event("server_started", self)
        self.ctrl_be.add_me_for_event("server_stopped", self)
Example #56
0
    def create_preview_table(self, clean_up = False):
        
        def create_chkbox(row):
            chk =  mforms.newCheckBox()
            chk.set_active(True)
            chk.add_clicked_callback(lambda checkbox = chk, output = row: operator.setitem(output, 'active', True if checkbox.get_active() else False))
            return chk
        
        type_items = {'is_string':'text','is_bignumber':'bigint', "is_geometry":'geometry', 'is_number':'int', 'is_float':'double', 'is_bin':'binary', 'is_date_or_time': 'datetime', 'is_json':'json'}
        def create_select_type(row):
            def sel_changed(sel, output):
                selection = sel.get_string_value()
                for v in type_items:
                    if selection in type_items[v]:
                        if output['type'] == 'double' and type_items[v] != 'double':
                            self.show_ds_box(False)
                        
                        if output['type'] == 'datetime' and type_items[v] != 'datetime':
                            self.show_df_box(False)
                            
                        if type_items[v] == 'double':
                            self.show_ds_box(True)
                        if type_items[v] == 'datetime':
                            self.show_df_box(True)
                            
                        output['type'] = type_items[v]
                        
                        break  
                
            sel = mforms.newSelector()
            sel.set_size(120, -1)

            items = [type for type in type_items.values() if not ((type == "geometry" or type == "json") and self.input_file_type == "json" and not self.is_server_5_7) ]
            sel.add_items(items)
            if not self.is_server_5_7 and (row['type'] == "geometry" or row["type"] == "json") and self.input_file_type == "json":
                row['type'] = "text" # If it's server older than 5.7 we don't have support for geojson so we can't properly import this file, instead we fallback to text
                log_info("Column %s is of type GeoJso but server doesn't support this, importing as text instead." % row['name'])
                
            for i, v in enumerate(items):
                if row['type'] == v:
                    sel.set_selected(i)
                    break
            
            sel.add_changed_callback(lambda: sel_changed(sel, row))
            return sel
        
        if self.preview_table is not None:
            self.column_scroll.remove()
            self.table_preview_box.set_spacing(16)
            if self.treeview_preview is not None:
                self.table_preview_box.remove(self.treeview_preview)
                self.treeview_preview = None
            self.preview_table = None
            self.dest_column_table_col = []
            self.field_type_table_col = []
            
        def create_select_dest_col(row, cols):
            sel = mforms.newSelector()
            sel.set_size(120, -1)
            sel.add_items(cols)
            for i, c in enumerate(cols):
                if c == row['dest_col']:
                    sel.set_selected(cols.index(c))
                    break
            sel.add_changed_callback(lambda output = row: operator.setitem(output, 'dest_col', sel.get_string_value()))
            return sel

        self.preview_table = mforms.newTable()
        self.preview_table.suspend_layout()
        self.column_scroll.add(self.preview_table)

        self.preview_table.set_column_count(5)
        self.preview_table.set_row_count(len(self.active_module._columns) + 1)
        self.preview_table.set_row_spacing(8)
        self.preview_table.set_column_spacing(8)
        
        if len(self.active_module._columns) >= 3:
            self.column_caption.set_size(-1, 200)
        else:
            self.column_caption.set_size(-1, 100)
        
        self.checkbox_list = []

        def sell_all(cols, active):
            for checkbox in self.checkbox_list:
                checkbox.set_active(bool(active))
            for row in self.column_mapping:
                row['active'] = active
        
        def find_column(col_name, index):
            if col_name in self.dest_cols:
                return col_name
            else:
                return self.dest_cols[index] if i < len(self.dest_cols) else None
        
        chk = mforms.newCheckBox()
        chk.set_active(True)
        chk.add_clicked_callback(lambda checkbox = chk, columns = self.active_module._columns: sell_all(columns, checkbox.get_active()))
        
        self.preview_table.add(chk, 0, 1, 0, 1, mforms.HFillFlag)
        self.preview_table.add(mforms.newLabel("Source Column"), 1, 2, 0, 1, mforms.HFillFlag)
        if not self.main.destination_page.new_table_radio.get_active():
            self.preview_table.add(mforms.newLabel("Dest Column"), 2, 3, 0, 1, mforms.HFillFlag)
        else:
            self.preview_table.add(mforms.newLabel("Field Type"), 3, 4, 0, 1, mforms.HFillFlag)
        self.column_mapping = []
        for i, col in enumerate(self.active_module._columns):
            row = {'active': True, 'name': col['name'], 'type' : None, 'col_no': i, 'dest_col': find_column(col['name'], i)}
            for c in col:
                if c.startswith('is_') and col[c]:
                    row['type'] = type_items[c]
                    break
            chk_box = create_chkbox(row)
            self.checkbox_list.append(chk_box)
            self.preview_table.add(chk_box, 0, 1, i+1, i+2, mforms.HFillFlag)
            self.preview_table.add(mforms.newLabel(str(col['name'].encode('utf8'))), 1, 2, i+1, i+2, mforms.HFillFlag)
            if not self.main.destination_page.new_table_radio.get_active():
                self.preview_table.add(create_select_dest_col(row, self.dest_cols), 2, 3, i+1, i+2, mforms.HFillFlag)
            else:
                self.preview_table.add(create_select_type(row), 3, 4, i+1, i+2, mforms.HFillFlag)
            self.column_mapping.append(row)
            
        self.treeview_preview = newTreeView(mforms.TreeFlatList)
        for i, col in enumerate(self.active_module._columns):
            self.treeview_preview.add_column(mforms.StringColumnType, str(col['name'].encode('utf8')), 75, True)
        self.treeview_preview.end_columns()
        
        
        if len(self.active_module._columns):
            col_values = []
            val_len = 0
            for col in self.active_module._columns:
                val_len = len(col['value']) if len(col['value']) > val_len else val_len

            col_len = len(self.active_module._columns)
            for i in range(0, val_len):
                row = []
                for j in range(0, col_len):
                    
                    if len(self.active_module._columns[j]['value']) > i:
                        row.append(self.active_module._columns[j]['value'][i])
                    else:
                        row.append("")
                col_values.append(row)

            for row in col_values:
                node = self.treeview_preview.add_node()
                for i, col in enumerate(row):
                    if hasattr(col, 'encode'):
                        node.set_string(i, str(col.encode('utf8')))
                    else:
                        node.set_string(i, str(col))

        self.treeview_preview.set_allow_sorting(True)
        self.treeview_preview.set_size(200, 100)
        self.table_preview_box.add(self.treeview_preview, False, True)
        self.preview_table.resume_layout()
    def __init__(self, main):
        WizardPage.__init__(self, main, "Data Transfer Setup")

        self.main.add_wizard_page(self, "DataMigration", "Data Transfer Setup")

        label = mforms.newLabel(
            "Select options for the copy of the migrated schema tables in the target MySQL server and click [Next >] to execute."
        )
        self.content.add(label, False, True)

        panel = mforms.newPanel(mforms.TitledBoxPanel)
        panel.set_title("Data Copy")
        self.content.add(panel, False, True)

        box = mforms.newBox(False)
        panel.add(box)
        box.set_padding(16)
        box.set_spacing(16)

        rid = mforms.RadioButton.new_id()

        self._copy_db = mforms.newRadioButton(rid)
        self._copy_db.set_text("Online copy of table data to target RDBMS")
        self._copy_db.add_clicked_callback(self._script_radio_option_callback)
        box.add(self._copy_db, False, True)

        # XXX TODO
        # box.add(mforms.newLabel(""), False, True)
        # self._add_script_checkbox_option(box, "dump_to_file", "Create a dump file with the data", "Dump File:", "Save As")

        if sys.platform == "win32":
            self._add_script_radiobutton_option(
                box,
                "copy_script",
                "Create a batch file to copy the data at another time",
                "Batch File:",
                "Save As",
                "You should edit this file to add the source and target server passwords before running it.",
                rid,
            )
        else:
            self._add_script_radiobutton_option(
                box,
                "copy_script",
                "Create a shell script to copy the data from outside Workbench",
                "Shell Script File:",
                "Save As",
                "You should edit this file to add the source and target server passwords before running it.",
                rid,
            )

        self._add_script_radiobutton_option(
            box,
            "bulk_copy_script",
            "Create a shell script to use native server dump and load abilities for fast migration",
            "Bulk Data Copy Script:",
            "Save As",
            "Edit the generated file and change passwords at the top of the generated script.\nRun it on the source server to create a zip package containing a data dump as well as a load script.\nCopy this to the target server, extract it, and run the import script. See the script output for further details.",
            rid,
        )

        panel = mforms.newPanel(mforms.TitledBoxPanel)
        panel.set_title("Options")
        self.content.add(panel, False, True)

        self.options_box = mforms.newBox(False)
        self.options_box.set_padding(12)
        self.options_box.set_spacing(8)
        panel.add(self.options_box)

        self._truncate_db = mforms.newCheckBox()
        self._truncate_db.set_text("Truncate target tables (i.e. delete contents) before copying data")
        self.options_box.add(self._truncate_db, False, True)

        hbox = mforms.newBox(True)
        hbox.set_spacing(16)
        hbox.add(mforms.newLabel("Worker tasks"), False, True)
        self._worker_count = mforms.newTextEntry()
        self._worker_count.set_value("2")
        self._worker_count.set_size(30, -1)
        hbox.add(self._worker_count, False, True)
        l = mforms.newImageBox()
        l.set_image(mforms.App.get().get_resource_path("mini_notice.png"))
        l.set_tooltip(
            "Number of tasks to use for data transfer. Each task will open a "
            + "connection to both source and target RDBMSes to copy table rows.\nDefault value 2."
        )
        hbox.add(l, False, True)
        self.options_box.add(hbox, False, True)

        self._debug_copy = mforms.newCheckBox()
        self._debug_copy.set_text("Enable debug output for table copy")
        self.options_box.add(self._debug_copy, False, True)

        ###

        self._advanced_panel = mforms.newPanel(mforms.TitledBoxPanel)
        self._advanced_panel.set_title("Tables to Copy")
        self.content.add(self._advanced_panel, True, True)

        box = mforms.newBox(False)
        box.set_padding(12)
        box.set_spacing(8)

        l = mforms.newLabel(
            """You can limit the number of rows to be copied for certain tables. Tables that are referenced by
foreign keys from other tables cannot be limited, unless data copy from the referencing tables is also disabled.
All tables are copied by default."""
        )
        l.set_style(mforms.SmallHelpTextStyle)
        box.add(l, False, True)

        self._tree = mforms.newTreeNodeView(mforms.TreeDefault)
        self._tree.add_column(mforms.IconStringColumnType, "Table", 200, False)
        self._tree.add_column(mforms.StringColumnType, "Limit Copy", 100, True)
        self._tree.add_column(mforms.StringColumnType, "Referencing Tables", 500, False)
        self._tree.end_columns()
        box.add(self._tree, True, True)
        self._advanced_panel.add(box)
        self._tree.set_cell_edited_callback(self._cell_edited)
        self._advbox_shown = False
        self._advanced_panel.show(False)