def handleContextMenu(name, sender, args):
    menu = mforms.fromgrt(args['menu'])

    selection = args['selection']

    # Add extra menu items to the SQL editor live schema tree context menu
    user_selection = None
    
    for s in selection:
        if s.type == 'db.Schema':
            user_selection = {'schema': to_unicode(s.name), 'table': None}
            break
        elif s.type == 'db.Table':
            user_selection = {'table': to_unicode(s.name), 'schema': to_unicode(s.schemaName)}
            break
        elif s.type == 'db.View':
            user_selection = {'table': to_unicode(s.name), 'schema': to_unicode(s.schemaName)}
            break
        else:
            return

    if user_selection:
        if user_selection['table']:
            item = mforms.newMenuItem("Table Data Export Wizard")
            item.add_clicked_callback(lambda sender=sender : showPowerExport(sender, user_selection))
            menu.insert_item(4, item)
예제 #2
0
    def preload_existing_tables(self):
        compare_in_lowercase = self.check_server_lower_case_table_names()

        rset = self.main.editor.executeManagementQuery("SHOW DATABASES", 1)
        if rset:
            ok = rset.goToFirstRow()
            self.table_list = {}
            db_list = []
            while ok:
                dbname = to_unicode(rset.stringFieldValue(0))
                if dbname.strip() in [
                        "mysql", "sys", "information_schema", "fabric",
                        "performance_schema"
                ]:
                    ok = rset.nextRow()
                    continue
                db_list.append(dbname)
                ok = rset.nextRow()
            if self.main.destination_table['schema']:
                rset = self.main.editor.executeManagementQuery(
                    u"SHOW FULL TABLES FROM `%s`" %
                    self.main.destination_table['schema'], 0)
                if rset:
                    ok = rset.goToFirstRow()
                    while ok:
                        if rset.stringFieldValue(1) == "BASE TABLE":
                            table_name = to_unicode(
                                rset.stringFieldValue(0)
                            ) if not compare_in_lowercase else to_unicode(
                                rset.stringFieldValue(0)).lower()
                            full_name = u"%s.%s" % (
                                self.main.destination_table['schema'],
                                table_name)
                            self.table_list[full_name] = {
                                'schema':
                                self.main.destination_table['schema'],
                                'table': table_name
                            }

                        ok = rset.nextRow()

            self.destination_table_sel.clear()
            self.destination_table_sel.add_items(self.table_list.keys())
            if self.main.destination_table[
                    'schema'] and self.main.destination_table['table']:
                table_name = u"%s.%s" % (self.main.destination_table['schema'],
                                         self.main.destination_table['table'])
                if table_name in self.table_list.keys():
                    self.destination_table_sel.set_selected(
                        self.table_list.keys().index(table_name))
            self.destination_database_sel.clear()
            self.destination_database_sel.add_items(db_list)
            if self.main.destination_table['schema']:
                self.destination_database_sel.set_selected(
                    db_list.index(self.main.destination_table['schema']))
    def start_export(self):
        if self._user_query:
            query = self._user_query
        else:
            query = self.get_query()

        rset = self._editor.executeManagementQuery(query, 1)
        if rset:
            if self._user_query: #We need to get columns info
                self.read_user_query_columns(rset)
                
            with open(self._filepath, 'wb') as jsonfile:
                jsonfile.write('['.encode('utf-8'))
                ok = rset.goToFirstRow()
                self._max_rows = rset.rowCount
                
                # Because there's no realiable way to use offset only, we'll do this here.
                offset = 0
                if self._offset and not self._limit:
                    offset = self._offset
                i = 0
                while ok:
                    if self._thread_event and self._thread_event.is_set():
                        log_debug2("Worker thread was stopped by user")
                        return False

                    i += 1
                    if offset > 0 and i <= offset:
                        ok = rset.nextRow()
                        continue

                    self.item_count = self.item_count + 1
                    self._current_row = rset.currentRow + 1
                    row = []
                    for col in self._columns:
                        if col['is_number'] or col['is_bignumber']:
                            row.append("\"%s\":%s" % (col['name'], json.dumps(rset.intFieldValueByName(col['name']))))
                        elif col['is_float']:
                            row.append("\"%s\":%s" % (col['name'], json.dumps(rset.floatFieldValueByName(col['name']))))
                        elif col['is_geometry']:
                            row.append("\"%s\":%s" % (col['name'], rset.geoJsonFieldValueByName(col['name'])))
                        else:
                            if col['type'] == "json":
                                row.append("\"%s\":%s" % (col['name'], to_unicode(rset.stringFieldValueByName(col['name']))))
                            else:
                                row.append("\"%s\":%s" % (col['name'], json.dumps(to_unicode(rset.stringFieldValueByName(col['name'])))))
                    ok = rset.nextRow()
                    line = "{%s}%s" % (', '.join(row), ",\n " if ok else "")
                    jsonfile.write(line.encode('utf-8'))
                    jsonfile.flush()
                jsonfile.write(']'.encode('utf-8'))

        return True
    def get_table_columns(self, table):
        cols = []
        try:
            rset = self.main.editor.executeManagementQuery(
                "SHOW COLUMNS FROM `%s`.`%s`" %
                (table['schema'], table['table']), 1)
        except grt.DBError as e:
            log_error("SHOW COLUMNS FROM `%s`.`%s` : %s" %
                      (table['schema'], table['table'], to_unicode(str(e))))
            rset = None

        if rset:
            ok = rset.goToFirstRow()
            while ok:
                col = {
                    'name': None,
                    'type': None,
                    'is_string': None,
                    'is_geometry': None,
                    'is_bignumber': None,
                    'is_number': None,
                    'is_date_or_time': None,
                    'is_bin': None,
                    'value': None
                }
                col['name'] = to_unicode(rset.stringFieldValueByName("Field"))
                col['type'] = rset.stringFieldValueByName("Type")
                col['is_number'] = any(x in col['type']
                                       for x in ['int', 'integer'])
                col['is_geometry'] = any(x in col['type'] for x in [
                    'geometry', 'geometrycollection', 'linestring',
                    'multilinestring', 'multipoint', 'multipolygon', 'point',
                    'polygon'
                ])
                col['is_bignumber'] = any(x in col['type'] for x in ['bigint'])
                col['is_float'] = any(x in col['type']
                                      for x in ['decimal', 'float', 'double'])
                col['is_string'] = any(
                    x in col['type']
                    for x in ['char', 'text', 'set', 'enum', 'json'])
                col['is_bin'] = any(x in col['type']
                                    for x in ['blob', 'binary'])
                col['is_date_or_time'] = any(
                    x in col['type']
                    for x in ['timestamp', 'datetime', 'date', 'time'])
                cols.append(col)
                ok = rset.nextRow()
        return cols
    def preload_existing_tables(self):
        self.table_list = {}

        rset = self.main.editor.executeManagementQuery(
            u"SHOW TABLES FROM `%s`" % self.main.source_table['schema'], 0)
        if rset:
            ok = rset.goToFirstRow()
            while ok:
                self.table_list[u"%s.%s" %
                                (self.main.source_table['schema'],
                                 to_unicode(rset.stringFieldValue(0)))] = {
                                     'schema':
                                     self.main.source_table['schema'],
                                     'table':
                                     to_unicode(rset.stringFieldValue(0))
                                 }
                ok = rset.nextRow()
 def get_columns(self):
     cols = []
     for r in range(self.simple_export.column_list.count()):
         node = self.simple_export.column_list.node_at_row(r)
         if node.get_bool(0):
             for col in self.simple_export.columns:
                 if col['name'] == to_unicode(node.get_string(1)):
                     cols.append(col)
     return cols
예제 #7
0
 def update(self, records=None):
     filtered_records = None
     if records:
         filtered_records = []
         for record in records:
             text = to_unicode(record[3])
             if self.filter_text == "All" or text.lower().find(self.filter_text.lower()) >= 0:
                 filtered_records.append(record)
     super(LogViewGeneric, self).update(filtered_records)
    def validate(self):
        compare_in_lowercase = self.check_server_lower_case_table_names()
        if self.existing_table_radio.get_active():
            self.main.destination_table = self.table_list[to_unicode(
                self.destination_table_sel.get_string_value())]
        else:
            self.main.destination_table['schema'] = to_unicode(
                self.destination_database_sel.get_string_value())
            self.main.destination_table['table'] = to_unicode(
                self.new_table_name.get_string_value()).strip()
            if len(self.main.destination_table['table']) == 0:
                mforms.Utilities.show_error(
                    "Table Import", "You need to specify new table name", "Ok",
                    "", "")
                return False

            if compare_in_lowercase:
                self.main.destination_table[
                    'table'] = self.main.destination_table['table'].lower()

            table_name = u"%s.%s" % (self.main.destination_table['schema'],
                                     self.main.destination_table['table'])

            if not self.drop_table_cb.get_active() and (
                    table_name in self.table_list
                    or self.check_if_table_exists(
                        self.main.destination_table['schema'],
                        self.main.destination_table['table'])):
                res = mforms.Utilities.show_message(
                    "Table Import",
                    "You specified to create a new table, but a table with the same name already exists in the selected schema. Would you like to drop it, or use the existing one and truncate?",
                    "Drop the table", "Use Existing One and Truncate it",
                    "Cancel")
                if res == mforms.ResultOk:
                    self.drop_table_cb.set_active(True)
                elif res == mforms.ResultCancel:
                    self.truncate_table_cb.set_active(True)
                    self.existing_table_radio.set_active(True)
                    self.destination_table_sel.set_selected(
                        self.table_list.keys().index(table_name))
                else:
                    return False
        return True
 def get_table_columns(self, table):
     cols = []
     try:
         rset = self.main.editor.executeManagementQuery(
             u"SHOW COLUMNS FROM `%s`.`%s`" %
             (table['schema'], table['table']), 1)
     except grt.DBError, e:
         log_error(u"SHOW COLUMNS FROM `%s`.`%s` : %s" %
                   (table['schema'], table['table'], to_unicode(e.message)))
         rset = None
    def load_dest_columns(self):
        try:
            rset = self.main.editor.executeManagementQuery(
                "SHOW COLUMNS FROM `%s`.`%s`" %
                (self.main.destination_table['schema'],
                 self.main.destination_table['table']), 1)
        except Exception as e:
            log_error(
                "SHOW COLUMNS FROM `%s`.`%s` : %s" %
                (self.main.destination_table['schema'],
                 self.main.destination_table['table'], to_unicode(str(e))))
            rset = None

        if rset:
            self.dest_cols = []
            ok = rset.goToFirstRow()
            while ok:
                self.dest_cols.append(
                    to_unicode(rset.stringFieldValueByName("Field")))
                ok = rset.nextRow()
예제 #11
0
class AdminUserDbPrivs(object):
    _owner = None

    def __init__(self, owner):
        self._owner = owner
        self.entries = []
        self._deleted_entries = []

    @property
    def schema_privilege_names(self):
        return self._owner._owner.schema_privilege_names

    def copy(self):
        copy = AdminUserDbPrivs(self._owner)

        copy.entries = [e.copy() for e in self.entries]
        copy._deleted_entries = self._deleted_entries[:]

        return copy

    def add_entry(self, db, privileges):
        entry = AdminUserDbPrivEntry(db, privileges)
        self.entries.append(entry)
        return entry

    def del_entry(self, index):
        self._deleted_entries.append(self.entries[index])
        del self.entries[index]


    def load(self):
        # Schema privileges from Db table
        query = GET_ACCOUNT_SCHEMA_PRIVS_QUERY % {"user": escape_sql_string(self._owner.username), "host": escape_sql_string(self._owner.host)}
        try:
            result = self._owner.ctrl_be.exec_query(query)
        except Exception, e:
            raise Exception("Error querying security information: %s" % e)

        self.entries = []

        while result.nextRow():
            privs = set()
            for priv in self.schema_privilege_names:
                value = result.stringByName(priv)
                if value == 'Y':
                    privs.add(priv)

            schema = to_unicode(result.stringByName("Db"))

            self.entries.append(AdminUserDbPrivEntry(schema, privs))

        self.entries.sort(lambda a, b: acl_compare(a.db, b.db))
        self._deleted_entries = []
 def load_dest_columns(self):
     try:
         rset = self.main.editor.executeManagementQuery(
             u"SHOW COLUMNS FROM `%s`.`%s`" %
             (self.main.destination_table['schema'],
              self.main.destination_table['table']), 1)
     except Exception, e:
         log_error(
             u"SHOW COLUMNS FROM `%s`.`%s` : %s" %
             (self.main.destination_table['schema'],
              self.main.destination_table['table'], to_unicode(e.message)))
         rset = None
    def create_account(self):
        def unique_name(user, host, counter=None):
            name = user + ( str(counter) if counter else '' )
            if (name, host) in self._accounts:
                name = unique_name(user, host, counter+1 if isinstance(counter, int) else 1)
            return name

        acct = AdminAccount(self)
        acct.host = u"%"
        acct.username = to_unicode(unique_name(u'newuser', acct.host))
        self._account_info_cache[acct.username+"@"+acct.host] = acct
        self._accounts.append((acct.username, acct.host))
        return acct
예제 #14
0
    def exec_query(self, q, auto_reconnect=True):
        ret = None
        if self.sql is not None:
            try:
                ret = self.sql.exec_query(q)
            except QueryError as e:
                log = "Error executing query %s: %s\n" % (
                    q, strip_password(to_unicode(str(e))))
                log_warning(log)
                if auto_reconnect and e.is_connection_error():
                    log_warning(
                        "exec_query: Loss of connection to mysql server was detected.\n"
                    )
                    self.handle_sql_disconnection(e)
                else:  # if exception is not handled, give a chance to the caller do it
                    raise e
        else:
            log_debug("sql connection is down\n")

        return ret
    def create_ui(self):
        self.suspend_layout()
        self.set_spacing(16)

        headingBox = mforms.newBox(True)
        headingBox.set_spacing(16)

        self.simple_export_box = mforms.newBox(False)
        self.simple_export_box.set_spacing(16)

        label = mforms.newLabel("Select source table for export:")
        label.set_style(mforms.BoldInfoCaptionStyle)
        headingBox.add(label, False, True)

        self.source_table_sel = mforms.newSelector()
        self.source_table_sel.set_size(self.get_width(), -1)
        self.preload_existing_tables()
        sorted_keys = self.table_list.keys()
        sorted_keys.sort()
        self.source_table_sel.add_items(sorted_keys)
        table_name = u"%s.%s" % (self.main.source_table['schema'],
                                 self.main.source_table['table'])
        if table_name in self.table_list.keys():
            self.source_table_sel.set_selected(sorted_keys.index(table_name))
        self.source_table_sel.add_changed_callback(
            lambda selector=self.source_table_sel: self.source_table_changed(
                to_unicode(selector.get_string_value())))
        headingBox.add(self.source_table_sel, False, True)

        self.simple_export_box.add(headingBox, False, True)

        self.simple_export = SimpleTabExport(self.main.editor, self)
        self.simple_export_box.add(self.simple_export, True, True)
        self.content.add(self.simple_export_box, True, True)

        self.advanced_export = AdvancedTabExport(self.main.editor, self)
        self.advanced_export.show(False)
        self.content.add(self.advanced_export, True, True)
        self.resume_layout()

        self.preload_table_info()
    def print_new_error_log_entries(self):
        if self.error_log_reader:
            self.error_log_reader.refresh()
            if self.error_log_position != self.error_log_reader.file_size:
                self.error_log_reader.chunk_start = self.error_log_position
                self.error_log_reader.chunk_end = self.error_log_reader.file_size
                self.error_log_position = self.error_log_reader.file_size
                records = self.error_log_reader.current()
                if records:
                    self.startup_msgs_log.append_text_with_encoding(
                        '\nFROM %s:\n' %
                        self.server_profile.error_log_file_path,
                        self._ctrl_be.server_helper.cmd_output_encoding, True)

                    log_lines = []
                    for line in records:
                        record_string = "  ".join(
                            to_unicode(log_piece) for log_piece in line)
                        log_lines.append(record_string)
                    log_output = "\n    ".join(log_lines)
                    self.startup_msgs_log.append_text_with_encoding(
                        '    ' + log_output + '\n',
                        self._ctrl_be.server_helper.cmd_output_encoding, True)
예제 #17
0
                        self.has_password_expired = True

        # get list of schema names
        schema_names = []
        try:
            result = self.ctrl_be.exec_query(LIST_SCHEMAS_QUERY)
        except QueryError, e:
            if e.error == 1142:
                raise PermissionDeniedError("Please make sure the account used has rights to the MySQL grant tables.\n%s" % e)
            raise e
        except Exception, e:
            raise Exception("Error querying privilege information: %s" % e)

        if result is not None:
            while result.nextRow():
                name = to_unicode(result.stringByName("Database"))
                schema_names.append(name)

        schema_names.sort()
        self._schema_names = schema_names

        # Get a list of the account names from the mysql.user table:
        accounts = []
        try:
            result = self.ctrl_be.exec_query(LIST_ACCOUNTS_QUERY)
        except Exception, e:
            raise Exception("Error querying privilege information: %s" % e)

        if result:
            while result.nextRow():
                user = to_unicode(result.stringByName("User"))
    def init_ui(self):
        if self._title:
            return

        if self._wait_table:
            self._pbar.stop()
            self._pbar = None
            self.remove(self._wait_table)
            self._wait_table = None

        self._title = mforms.newLabel(to_unicode(self.caption))
        self._title.set_style(mforms.BigBoldStyle)
        self.add(self._title, False, True)

        self._column_file = None

        if self.description:
            self._description = mforms.newLabel(to_unicode(self.description))
            self.add(self._description, False, True)

        self._tree = mforms.newTreeView(mforms.TreeFlatList
                                        | mforms.TreeAltRowColors
                                        | mforms.TreeShowColumnLines)
        self._tree.set_selection_mode(mforms.TreeSelectMultiple)
        self._tree.add_column_resized_callback(self._tree_column_resized)
        c = 0

        self._hmenu = mforms.newContextMenu()
        self._hmenu.add_will_show_callback(self._header_menu_will_show)
        self._tree.set_header_menu(self._hmenu)

        self._column_types = []
        self._column_units = []
        self._column_names = []
        self._column_titles = []
        for i, (column, cname, ctype,
                length) in enumerate(self.get_view_columns()):
            unit = None
            if type(ctype) is tuple:
                ctype, unit = ctype
            unit = grt.root.wb.state.get(
                "wb.admin.psreport:unit:%s:%i" % (self.view, i), unit)

            width = min(max(length, 40), 300)
            width = grt.root.wb.state.get(
                "wb.admin.psreport:width:%s:%i" % (self.view, i), width)

            label = to_unicode(self.column_label(column))
            self._column_units.append(unit)
            self._column_names.append(cname)
            self._column_titles.append(label)
            self._column_types.append(ctype)

            if unit:
                self._tree.add_column(ctype, label + " (%s)" % unit, width,
                                      False)
            else:
                self._tree.add_column(ctype, label, width, False)
            c += 1
        self._tree.end_columns()
        self._tree.set_allow_sorting(True)
        self.add(self._tree, True, True)

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

        btn = mforms.newButton()
        btn.set_text("Export...")
        btn.add_clicked_callback(self.do_export)
        bbox.add(btn, False, True)

        btn = mforms.newButton()
        btn.set_text("Copy Selected")
        btn.add_clicked_callback(self.do_copy)
        bbox.add(btn, False, True)

        btn = mforms.newButton()
        btn.set_text("Copy Query")
        btn.add_clicked_callback(self.do_copy_query)
        bbox.add(btn, False, True)

        self._refresh = mforms.newButton()
        self._refresh.set_text("Refresh")
        self._refresh.add_clicked_callback(self.do_refresh)
        bbox.add_end(self._refresh, False, True)
        self.add(bbox, False, True)
class DataInputPage(WizardPage):
    def __init__(self, owner):
        WizardPage.__init__(self, owner, "Select data for export")
        self.simple_export = None
        self.advanced_export = None
        self._showing_simple = True
        self.table_list = {}
        
    def create_ui(self):
        self.suspend_layout()
        self.set_spacing(16)
        
        headingBox = mforms.newBox(True)
        headingBox.set_spacing(16)
        
        self.simple_export_box = mforms.newBox(False)
        self.simple_export_box.set_spacing(16)
        
        label = mforms.newLabel("Select source table for export:")
        label.set_style(mforms.BoldInfoCaptionStyle)
        headingBox.add(label, False, True)
        
        self.source_table_sel = mforms.newSelector()
        self.source_table_sel.set_size(self.get_width(), -1)
        self.preload_existing_tables()
        sorted_keys = self.table_list.keys()
        sorted_keys.sort()
        self.source_table_sel.add_items(sorted_keys)
        table_name = u"%s.%s" % (self.main.source_table['schema'], self.main.source_table['table'])
        if table_name in self.table_list.keys():
            self.source_table_sel.set_selected(sorted_keys.index(table_name))
        self.source_table_sel.add_changed_callback(lambda selector = self.source_table_sel: self.source_table_changed(to_unicode(selector.get_string_value())))
        headingBox.add(self.source_table_sel, False, True)
        
        self.simple_export_box.add(headingBox, False, True)
        
        self.simple_export = SimpleTabExport(self.main.editor, self)
        self.simple_export_box.add(self.simple_export, True, True)
        self.content.add(self.simple_export_box, True, True)
        
        self.advanced_export = AdvancedTabExport(self.main.editor, self)
        self.advanced_export.show(False)
        self.content.add(self.advanced_export, True, True)
        self.resume_layout()
        
        self.preload_table_info()
        
        
    def get_table_columns(self, table):
        cols = []
        try:
            rset = self.main.editor.executeManagementQuery(u"SHOW COLUMNS FROM `%s`.`%s`" % (table['schema'], table['table']), 1)
        except grt.DBError, e:
            log_error(u"SHOW COLUMNS FROM `%s`.`%s` : %s" % (table['schema'], table['table'], to_unicode(e.message)))
            rset = None
            
        if rset:
            ok = rset.goToFirstRow()
            while ok:
                col = {'name': None, 'type': None, 'is_string': None, 'is_geometry':None, 'is_bignumber':None, 'is_number': None, 'is_date_or_time': None, 'is_bin': None, 'value': None}
                col['name'] = to_unicode(rset.stringFieldValueByName("Field"))
                col['type'] = rset.stringFieldValueByName("Type")
                col['is_number'] = any(x in col['type'] for x in ['int', 'integer'])
                col['is_geometry'] = any(x in col['type'] for x in ['geometry','geometrycollection', 'linestring', 'multilinestring', 'multipoint', 'multipolygon', 'point' , 'polygon'])
                col['is_bignumber'] = any(x in col['type'] for x in ['bigint'])
                col['is_float'] = any(x in col['type'] for x in ['decimal', 'float', 'double'])  
                col['is_string'] = any(x in col['type'] for x in ['char', 'text', 'set', 'enum', 'json'])
                col['is_bin'] = any(x in col['type'] for x in ['blob', 'binary'])  
                col['is_date_or_time'] = any(x in col['type'] for x in ['timestamp', 'datetime', 'date', 'time'])
                cols.append(col)
                ok = rset.nextRow()
        return cols
예제 #20
0
    def import_script(self, path, default_schema=None, default_charset="utf8"):
        if not self._tool_path:
            raise RuntimeError(
                "mysql command line client not found. Please fix its path in Preferences -> Administration"
            )

        is_windows = platform.system() == 'Windows'

        if is_windows:
            params = ['"%s"' % self._tool_path]
            pwdfile = tempfile.NamedTemporaryFile(delete=False, suffix=".cnf")
            pwdfilename = pwdfile.name
            tmpdir = None
        else:
            params = [to_unicode(self._tool_path)]
            # use a pipe to feed the password to the client
            tmpdir = tempfile.mkdtemp()
            pwdfilename = os.path.join(tmpdir, 'extraparams.cnf')
            os.mkfifo(pwdfilename)
        params.append('--defaults-extra-file=' + pwdfilename)

        if default_charset:
            params.append("--default-character-set=%s" % default_charset)
        params += self._connection_params
        params += self._extra_params

        if default_schema:
            params.append(default_schema)

        cmdstr = " ".join(params)

        workdir = os.path.dirname(path)

        log_info("Feeding data from %s to %s (cwd=%s)\n" %
                 (path, cmdstr, workdir))
        p1 = None
        try:
            self.report_progress("Preparing...", None, None)
            if not is_windows:
                try:
                    p1 = subprocess.Popen(params,
                                          cwd=workdir,
                                          stdin=subprocess.PIPE,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.STDOUT,
                                          encoding='utf8')
                except OSError as exc:
                    log_error("Error executing command %s\n%s\n" %
                              (" ".join(params), exc))
                    raise RuntimeError("Error executing %s:\n%s" %
                                       (" ".join(params), str(exc)))

            # in !Windows feed password to client after it's started (otherwise the fifo would block on open for writing)
            with open(pwdfilename, 'w') as pwdfile:
                pwdfile.write('[client]\npassword='******''
                pwdfile.write(self._password.replace("\\", "\\\\"))
                pwdfile.write('\n')

            if is_windows:
                try:
                    info = subprocess.STARTUPINFO()
                    info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                    info.wShowWindow = subprocess.SW_HIDE
                    # Command line can contain object names in case of export and filename in case of import
                    # Object names must be in utf-8 but filename must be encoded in the filesystem encoding,
                    # which probably isn't utf-8 in windows.
                    log_debug("Executing command: %s\n" % cmdstr)
                    p1 = subprocess.Popen(cmdstr,
                                          cwd=workdir,
                                          stdout=subprocess.PIPE,
                                          stdin=subprocess.PIPE,
                                          stderr=subprocess.STDOUT,
                                          startupinfo=info,
                                          shell=cmdstr[0] != '"',
                                          encoding='utf8')
                except OSError as exc:
                    log_error("Error executing command %s\n%s\n" %
                              (cmdstr, str(exc)))
                    import traceback
                    traceback.print_exc()
                    raise RuntimeError("Error executing %s:\n%s" %
                                       (cmdstr, str(exc)))

            # do the import
            total_size = os.stat(path).st_size
            processed = 0
            self.report_progress("Importing %s..." % os.path.basename(path), 0,
                                 total_size)
            stdout_q, thr = start_reading_from(p1.stdout)

            with open(path, "r") as input_file:
                while p1 and p1.poll() == None:
                    try:
                        if stdout_q:
                            text = stdout_q.get_nowait()
                            if text:
                                log_info("Task stdout: %s\n" % text)
                                if 'Access denied for user' in text:
                                    raise grt.DBLoginError(text)
                                elif "Can't open named pipe to host" in text and sys.platform.lower(
                                ) == "win32":
                                    text = "%s\n%s" % (
                                        text,
                                        "Please check if the server started with the --enabled-named-pipe parameter. The parameter can also be set in the config file."
                                    )
                                self.report_output(text.strip())
                            elif text is None:
                                stdout_q = None
                    except Empty:
                        pass

                    line = input_file.readline()
                    if not line:
                        break
                    processed += len(line)
                    try:
                        p1.stdin.write(line)
                    except IOError as e:
                        log_error(
                            "Exception writing to stdin from cmdline client: %s\n"
                            % e)
                        if e.errno == 32:  # broken pipe
                            log_error("Broken pipe from child process\n")
                            break
                        elif e.errno == 22:  # invalid argument (happens in Windows, when child process just dies)
                            log_error("Broken pipe from child process\n")
                            break
                        raise e
                    self.report_progress(None, processed, total_size)

            # close the writer end of the client's pipe, so it can exit
            p1.stdin.close()

            self.report_progress("Finished executing script", processed,
                                 total_size)

            # flush queue from reader
            if stdout_q:
                while True:
                    text = stdout_q.get()
                    if text is None:
                        break
                    log_info("Task stdout: %s\n" % text)
                    if 'Access denied for user' in text:
                        raise grt.DBLoginError(text)
                    elif "Can't open named pipe to host" in text and sys.platform.lower(
                    ) == "win32":
                        text = "%s\n%s" % (
                            text,
                            "Please check if the server started with the --enabled-named-pipe parameter. The parameter can also be set in the config file."
                        )
                    self.report_output(text.strip())

            # let reader thread die
            thr.join()

            p1.wait()

            exitcode = p1.returncode

            log_info("mysql tool exited with code %s\n" % exitcode)

            if exitcode != 0:
                self.report_progress(
                    "Operation failed with exitcode " + str(exitcode), None,
                    None)
            else:
                self.report_progress("Operation completed successfully", None,
                                     None)

            return exitcode
        finally:
            if pwdfilename:
                os.remove(pwdfilename)
            if tmpdir:
                os.rmdir(tmpdir)
class ConfigurationPage(WizardPage):
    def __init__(self, owner):
        WizardPage.__init__(self,
                            owner,
                            "Configure Import Settings",
                            wide=True)

        self.last_analyze_status = False
        self.input_file_type = 'csv'
        self.active_module = self.main.formats[0]  # csv
        self.encoding_list = {
            'cp1250 (windows-1250)': 'cp1250',
            'latin2 (iso8859-2)': 'iso8859_2',
            'latin1 (iso8859-1)': 'latin_1',
            'utf-8': 'utf-8',
            'utf-16': 'utf-16'
        }
        self.dest_cols = []
        self.column_mapping = []
        self.ds_show_count = 0
        self.df_show_count = 0
        self.opts_mapping = {}
        self.is_server_5_7 = Version.fromgrt(
            self.main.editor.serverVersion
        ).is_supported_mysql_version_at_least(Version.fromstr("5.7.5"))

    def go_cancel(self):
        self.main.close()

    def page_activated(self, advancing):
        if advancing:
            self.get_module()

        if advancing and not self.main.destination_page.new_table_radio.get_active(
        ):
            self.load_dest_columns()
        super(ConfigurationPage, self).page_activated(advancing)

        if advancing:
            self.call_create_preview_table()

    def create_ui(self):
        self.set_spacing(16)
        format_box = mforms.newBox(True)
        format_box.set_spacing(8)
        format_box.add(
            mforms.newLabel("Detected file format: %s" % self.input_file_type),
            False, True)
        if len(self.active_module.options) != 0:
            advanced_opts_btn = mforms.newButton(mforms.ToolButton)
            advanced_opts_btn.set_size(-1, 16)
            advanced_opts_btn.set_icon(
                mforms.App.get().get_resource_path("admin_option_file.png"))
            advanced_opts_btn.add_clicked_callback(
                lambda: self.optpanel.show(False)
                if self.optpanel.is_shown() else self.optpanel.show(True))
            format_box.add(advanced_opts_btn, False, True)

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

        if len(self.active_module.options) != 0:
            self.optpanel = mforms.newPanel(mforms.TitledBoxPanel)
            self.optpanel.set_title("Options:")

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

            def set_selector_entry(selector, output):
                operator.setitem(
                    output, 'value',
                    output['opts'][str(selector.get_string_value())])
                mforms.Utilities.add_timeout(0.1,
                                             self.call_create_preview_table)

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

        if self.input_file_type == 'csv':
            # We show encoding box only for csv as json can be only utf-8, utf-16 according to rfc
            self.encoding_box = mforms.newBox(True)
            self.encoding_box.set_spacing(16)
            self.encoding_box.add(mforms.newLabel("Encoding: "), False, True)
            self.encoding_sel = mforms.newSelector()
            self.encoding_sel.set_size(250, -1)
            self.encoding_box.add(self.encoding_sel, False, True)

            for i, e in enumerate(self.encoding_list):
                self.encoding_sel.add_item(e)
                if self.encoding_list[e] == 'utf-8':
                    self.encoding_sel.set_selected(i)
            self.encoding_sel.add_changed_callback(self.encoding_changed)
            self.content.add(self.encoding_box, False, True)

        self.table_preview_box = mforms.newBox(False)
        self.table_preview_box.set_spacing(16)
        self.preview_table = None
        self.content.add(self.table_preview_box, True, True)

        self.column_caption = mforms.newPanel(mforms.BorderedPanel)
        self.column_caption.set_title("Columns:")
        self.column_caption.set_size(-1, 100)
        self.column_scroll = mforms.newScrollPanel(0)
        self.column_caption.add(self.column_scroll)
        self.table_preview_box.add(self.column_caption, True, True)

        extra_opts = mforms.newBox(False)
        extra_opts.set_spacing(16)

        self.ds_box = mforms.newBox(True)
        self.ds_box.set_spacing(8)
        extra_opts.add(self.ds_box, False, True)

        self.df_box = mforms.newBox(True)
        self.df_box.set_spacing(8)
        extra_opts.add_end(self.df_box, False, True)

        self.ds_box.add(mforms.newLabel("Decimal Separator:"), False, True)
        self.ds_entry = mforms.newTextEntry()
        self.ds_entry.set_value('.')
        self.ds_entry.set_size(30, -1)
        self.ds_box.add(self.ds_entry, False, True)
        self.ds_box.show(False)

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

        self.content.add_end(extra_opts, False, True)

    def make_label_with_tooltip(self, lbl, tooltip):
        box = mforms.newBox(True)
        box.add(mforms.newLabel(lbl), False, True)
        l = mforms.newImageBox()
        l.set_image(mforms.App.get().get_resource_path("mini_notice.png"))
        l.set_tooltip(tooltip)
        box.add(l, False, True)
        return box

    def load_dest_columns(self):
        try:
            rset = self.main.editor.executeManagementQuery(
                u"SHOW COLUMNS FROM `%s`.`%s`" %
                (self.main.destination_table['schema'],
                 self.main.destination_table['table']), 1)
        except Exception, e:
            log_error(
                u"SHOW COLUMNS FROM `%s`.`%s` : %s" %
                (self.main.destination_table['schema'],
                 self.main.destination_table['table'], to_unicode(e.message)))
            rset = None

        if rset:
            self.dest_cols = []
            ok = rset.goToFirstRow()
            while ok:
                self.dest_cols.append(
                    to_unicode(rset.stringFieldValueByName("Field")))
                ok = rset.nextRow()