def _get_descriptions(self): """Read a column descriptor packet for each column in the result.""" self.fields = [] self.converters = [] use_unicode = self.connection.use_unicode description = [] for i in range(self.field_count): field = yield from self.connection._read_packet( FieldDescriptorPacket) self.fields.append(field) description.append(field.description()) field_type = field.type_code if use_unicode: if field_type in TEXT_TYPES: charset = charset_by_id(field.charsetnr) if charset.is_binary: # TEXTs with charset=binary means BINARY types. encoding = None else: encoding = charset.encoding else: encoding = 'ascii' else: encoding = None converter = self.connection.decoders.get(field_type) if converter is through: converter = None self.converters.append((encoding, converter)) eof_packet = yield from self.connection._read_packet() assert eof_packet.is_eof_packet(), 'Protocol error, expecting EOF' self.description = tuple(description)
def _read_row_from_packet(self, packet): use_unicode = self.connection.use_unicode row = [] for field in self.fields: data = packet.read_length_coded_string() if data is not None: field_type = field.type_code if use_unicode: if field_type in TEXT_TYPES: charset = charset_by_id(field.charsetnr) if use_unicode and not charset.is_binary: # TEXTs with charset=binary means BINARY types. data = data.decode(charset.encoding) else: data = data.decode() converter = self.connection.decoders.get(field_type) # logger.debug('DEBUG: field={}, converter={}'.format( # field, converter)) # logger.debug('DEBUG: DATA = {}'.format(data)) if converter is not None: data = converter(data) row.append(data) return tuple(row)
def _get_server_information(self): i = 0 packet = yield from self._read_packet() data = packet.get_all_data() # logger.debug(dump_packet(data)) self.protocol_version = byte2int(data[i:i + 1]) i += 1 server_end = data.find(b'\0', i) self.server_version = data[i:server_end].decode('latin1') i = server_end + 1 self.server_thread_id = struct.unpack('<I', data[i:i + 4]) i += 4 self.salt = data[i:i + 8] i += 9 # 8 + 1(filler) self.server_capabilities = struct.unpack('<H', data[i:i + 2])[0] i += 2 if len(data) >= i + 6: lang, stat, cap_h, salt_len = struct.unpack('<BHHB', data[i:i + 6]) i += 6 self.server_language = lang self.server_charset = charset_by_id(lang).name self.server_status = stat # logger.debug("server_status: %s" % _convert_to_str(stat)) self.server_capabilities |= cap_h << 16 # logger.debug("salt_len: %s" % _convert_to_str(salt_len)) salt_len = max(12, salt_len - 9) # reserved i += 10 if len(data) >= i + salt_len: # salt_len includes auth_plugin_data_part_1 and filler self.salt += data[i:i + salt_len] i += salt_len i += 1 # AUTH PLUGIN NAME may appear here. if self.server_capabilities & CLIENT.PLUGIN_AUTH and len(data) >= i: # Due to Bug#59453 the auth-plugin-name is missing the terminating # NUL-char in versions prior to 5.5.10 and 5.6.2. # ref: https://dev.mysql.com/doc/internals/en/ # connection-phase-packets.html#packet-Protocol::Handshake # didn't use version checks as mariadb is corrected and reports # earlier than those two. server_end = data.find(b'\0', i) if server_end < 0: # pragma: no cover - very specific upstream bug # not found \0 and last field so take it all self._auth_plugin_name = data[i:].decode('latin1') else: self._auth_plugin_name = data[i:server_end].decode('latin1')
def _get_server_information(self): i = 0 packet = yield from self._read_packet() data = packet.get_all_data() # logger.debug(dump_packet(data)) self.protocol_version = byte2int(data[i:i + 1]) i += 1 server_end = data.find(int2byte(0), i) self.server_version = data[i:server_end].decode('latin1') i = server_end + 1 self.server_thread_id = struct.unpack('<I', data[i:i + 4]) i += 4 self.salt = data[i:i + 8] i += 9 # 8 + 1(filler) self.server_capabilities = struct.unpack('<H', data[i:i + 2])[0] i += 2 if len(data) >= i + 6: lang, stat, cap_h, salt_len = struct.unpack('<BHHB', data[i:i + 6]) i += 6 self.server_language = lang self.server_charset = charset_by_id(lang).name self.server_status = stat # logger.debug("server_status: %s" % _convert_to_str(stat)) self.server_capabilities |= cap_h << 16 # logger.debug("salt_len: %s" % _convert_to_str(salt_len)) salt_len = max(12, salt_len - 9) # reserved i += 10 if len(data) >= i + salt_len: # salt_len includes auth_plugin_data_part_1 and filler self.salt += data[i:i + salt_len]
def escape_dict(value): from pymysql import escape_dict from pymysql.charset import charset_by_id charset = charset_by_id(224) # utf8mb4 utf8mb4_unicode_ci return escape_dict(value, charset)
def _get_server_information(self): i = 0 # read row packet raw_data = self._read_packet_raw() # with ignoring 4-byte header packet = MysqlPacket(raw_data[4:], self.encoding) packet.check_error() data = packet.get_all_data() self.protocol_version = byte2int(data[i:i + 1]) i += 1 server_end = data.find(b'\0', i) self.server_version = data[i:server_end].decode('latin1') i = server_end + 1 self.server_thread_id = struct.unpack('<I', data[i:i + 4]) i += 4 self.salt = data[i:i + 8] i += 9 # 8 + 1(filler) self.server_capabilities = struct.unpack('<H', data[i:i + 2])[0] i += 2 if len(data) >= i + 6: lang, stat, cap_h, salt_len = struct.unpack('<BHHB', data[i:i + 6]) i += 6 # TODO: deprecate server_language and server_charset. # mysqlclient-python doesn't provide it. self.server_language = lang try: self.server_charset = charset_by_id(lang).name except KeyError: # unknown collation self.server_charset = None self.server_status = stat if DEBUG: print("server_status: %x" % stat) self.server_capabilities |= cap_h << 16 if DEBUG: print("salt_len:", salt_len) salt_len = max(12, salt_len - 9) # reserved i += 10 if len(data) >= i + salt_len: # salt_len includes auth_plugin_data_part_1 and filler self.salt += data[i:i + salt_len] i += salt_len i += 1 # AUTH PLUGIN NAME may appear here. if self.server_capabilities & CLIENT.PLUGIN_AUTH and len(data) >= i: # Due to Bug#59453 the auth-plugin-name is missing the terminating # NUL-char in versions prior to 5.5.10 and 5.6.2. # ref: https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake # didn't use version checks as mariadb is corrected and reports # earlier than those two. server_end = data.find(b'\0', i) if server_end < 0: # pragma: no cover - very specific upstream bug # not found \0 and last field so take it all self._auth_plugin_name = data[i:].decode('latin1') else: self._auth_plugin_name = data[i:server_end].decode('latin1') return raw_data