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