python版mysql协议_python版本的mysql text resultset row协议代码实现

本文详细介绍了Python版本的MySQL Text ResultSet Row协议的实现,包括预处理包类`PreparPacket`和解包包类`UnpackPacket`的各个函数,涉及COM_Query、COM_STMT_PREPARE、COM_STMT_EXECUTE等命令的处理,以及数据的编码解码和结果集解析。通过实例展示了如何使用这些类执行SQL查询并获取结果。
摘要由CSDN通过智能技术生成

import struct,sys

from socket import *

from contextlib import closing

import hashlib,os

from functools import partial

from prettytable import PrettyTable #[liuzhuan] 引入表格

sha1_new = partial(hashlib.new, 'sha1')

SHA1_HASH_SIZE = 20

MULTI_RESULTS = 1 << 17

SECURE_CONNECTION = 1 << 15

CLIENT_PLUGIN_AUTH = 1 << 19

CLIENT_CONNECT_ATTRS = 1<< 20

CLIENT_PROTOCOL_41 = 1 << 9

CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 1<<21

CLIENT_DEPRECATE_EOF = 1 << 24

LONG_PASSWORD = 1

LONG_FLAG = 1 << 2

PROTOCOL_41 = 1 << 9

TRANSACTIONS = 1 << 13

CAPABILITIES = (

LONG_PASSWORD | LONG_FLAG | PROTOCOL_41 | TRANSACTIONS

| SECURE_CONNECTION | MULTI_RESULTS

| CLIENT_PLUGIN_AUTH | CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | CLIENT_CONNECT_ATTRS | CLIENT_DEPRECATE_EOF)

CLIENT_CONNECT_WITH_DB = 9

max_packet_size = 2 ** 24 - 1

charset_id = 45

class PreparPacket(object):

#类内函数实现

def __init__(self):

pass

#类内函数实现

def __null_bitmap(self,num_params):

_bytes = int((num_params + 7) / 8)

if _bytes == 1:

return bytearray(struct.pack('B',0))

elif _bytes == 2:

return bytearray(struct.pack('H', 0))

elif _bytes == 3:

return bytearray(struct.pack('HB', 0,0))

elif _bytes == 4:

return bytearray(struct.pack('I', 0))

#类内函数实现

def is_null(self,null_bytes,pos):

bit = null_bytes[int(pos / 8)]

if type(bit) is str:

bit = ord(bit)

return bit & (1 << (pos % 8))

#类内函数实现

def COM_Query(self, sql):

return struct.pack('B', 3) + sql.encode('utf8')

#类内函数实现

def COM_STMT_PREPARE(self,sql):

return struct.pack('B',0x16) + sql.encode('utf8')

#类内函数实现

def COM_STMT_EXECUTE(self,statement_id,flags,num_params,values,column_info):

_pack = struct.pack('

if num_params > 0:

_null_map = self.__null_bitmap(num_params)

for i,k in enumerate(values):

if k == None:

bytes_pos = int(i / 8)

bit_pos = int(i % 8)

_null_map[bytes_pos] |= 1 << bit_pos

_pack += _null_map + struct.pack('B',1)

_v = b''

for col_name in values:

col_type = 0x0f # default string

for col in column_info:

if col['name'].decode() == col_name:

col_type = col['type']

_pack += struct.pack('H',col_type)

if col_type in (0xfd,0xfe,0x0f):

_v += struct.pack('B',len(values[col_name]))

_v += values[col_name].encode('utf8')

elif col_type == 0x01:

_v += struct.pack('B',values[col_name])

elif col_type == 0x02:

_v += struct.pack('

elif col_type in (0x03,0x09):

_v += struct.pack('

elif col_type == 0x08:

_v += struct.pack('

return _pack + _v

#类内函数实现

def Prepar_head(self,playload_length,seq_id):

return struct.pack('

#类内函数实现

def handshakeresponsepacket(self,server_packet_info,user,password,database=None):

client_flag = 0

client_flag |= CAPABILITIES

if database:

client_flag |= CLIENT_CONNECT_WITH_DB

server_version = (server_packet_info['server_version']).decode()

if int(server_version.split('.', 1)[0]) >= 5:

client_flag |= MULTI_RESULTS

response_packet = struct.pack('

response_packet += user.encode() + b'\0'

sha1_password = self.sha1_password(password=password,auth_plugin_data=server_packet_info['auth_plugin_data'])

if server_packet_info['capability_flags'] & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA:

response_packet += struct.pack('!B',len(sha1_password)) + sha1_password

elif server_packet_info['capability_flags'] & SECURE_CONNECTION:

response_packet += struct.pack('B',len(sha1_password)) + sha1_password

else:

response_packet += sha1_password + b'\0'

if server_packet_info['capability_flags'] & CLIENT_CONNECT_WITH_DB:

if database:

response_packet += database.encode()

response_packet += b'\0'

if server_packet_info['capability_flags'] & CLIENT_PLUGIN_AUTH:

response_packet += b'' + b'\0'

if server_packet_info['capability_flags'] & CLIENT_CONNECT_ATTRS:

_connect_attrs = {

'_client_name': 'pymysql',

'_pid': str(os.getpi

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值